Refactor course search into openedx/features
This commit is contained in:
committed by
Diana Huang
parent
7721237989
commit
0096c80a13
@@ -2230,6 +2230,7 @@ INSTALLED_APPS = (
|
|||||||
# Features
|
# Features
|
||||||
'openedx.features.course_bookmarks',
|
'openedx.features.course_bookmarks',
|
||||||
'openedx.features.course_experience',
|
'openedx.features.course_experience',
|
||||||
|
'openedx.features.course_search',
|
||||||
'openedx.features.enterprise_support',
|
'openedx.features.enterprise_support',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
1
lms/static/course_search
Symbolic link
1
lms/static/course_search
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../openedx/features/course_search/static/course_search
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
(function(define) {
|
|
||||||
define([
|
|
||||||
'js/search/base/views/search_form'
|
|
||||||
], function(SearchForm) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return SearchForm.extend({
|
|
||||||
el: '#courseware-search-bar'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})(define || RequireJS.define);
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
(function(define) {
|
|
||||||
define([
|
|
||||||
'js/search/base/views/search_item_view'
|
|
||||||
], function(SearchItemView) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return SearchItemView.extend({
|
|
||||||
templateId: '#course_search_item-tpl'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})(define || RequireJS.define);
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
(function(define) {
|
|
||||||
define([
|
|
||||||
'js/search/base/views/search_form'
|
|
||||||
], function(SearchForm) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return SearchForm.extend({
|
|
||||||
el: '#dashboard-search-bar'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})(define || RequireJS.define);
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
(function(define) {
|
|
||||||
define([
|
|
||||||
'js/search/base/views/search_item_view'
|
|
||||||
], function(SearchItemView) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return SearchItemView.extend({
|
|
||||||
templateId: '#dashboard_search_item-tpl'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})(define || RequireJS.define);
|
|
||||||
@@ -28,6 +28,7 @@ var options = {
|
|||||||
sourceFiles: [
|
sourceFiles: [
|
||||||
{pattern: 'coffee/src/**/!(*spec).js'},
|
{pattern: 'coffee/src/**/!(*spec).js'},
|
||||||
{pattern: 'course_bookmarks/**/!(*spec).js'},
|
{pattern: 'course_bookmarks/**/!(*spec).js'},
|
||||||
|
{pattern: 'course_search/**/!(*spec).js'},
|
||||||
{pattern: 'discussion/js/**/!(*spec).js'},
|
{pattern: 'discussion/js/**/!(*spec).js'},
|
||||||
{pattern: 'js/**/!(*spec|djangojs).js'},
|
{pattern: 'js/**/!(*spec|djangojs).js'},
|
||||||
{pattern: 'lms/js/**/!(*spec).js'},
|
{pattern: 'lms/js/**/!(*spec).js'},
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
modules: getModulesList([
|
modules: getModulesList([
|
||||||
'course_bookmarks/js/course_bookmarks_factory',
|
'course_bookmarks/js/course_bookmarks_factory',
|
||||||
|
'course_search/js/course_search_factory',
|
||||||
|
'course_search/js/dashboard_search_factory',
|
||||||
'discussion/js/discussion_board_factory',
|
'discussion/js/discussion_board_factory',
|
||||||
'discussion/js/discussion_profile_page_factory',
|
'discussion/js/discussion_profile_page_factory',
|
||||||
'js/api_admin/catalog_preview_factory',
|
'js/api_admin/catalog_preview_factory',
|
||||||
@@ -32,8 +34,6 @@
|
|||||||
'js/header_factory',
|
'js/header_factory',
|
||||||
'js/learner_dashboard/program_details_factory',
|
'js/learner_dashboard/program_details_factory',
|
||||||
'js/learner_dashboard/program_list_factory',
|
'js/learner_dashboard/program_list_factory',
|
||||||
'js/search/course/course_search_factory',
|
|
||||||
'js/search/dashboard/dashboard_search_factory',
|
|
||||||
'js/student_account/logistration_factory',
|
'js/student_account/logistration_factory',
|
||||||
'js/student_account/views/account_settings_factory',
|
'js/student_account/views/account_settings_factory',
|
||||||
'js/student_account/views/finish_auth_factory',
|
'js/student_account/views/finish_auth_factory',
|
||||||
|
|||||||
@@ -676,6 +676,7 @@
|
|||||||
'course_bookmarks/js/spec/bookmark_button_view_spec.js',
|
'course_bookmarks/js/spec/bookmark_button_view_spec.js',
|
||||||
'course_bookmarks/js/spec/bookmarks_list_view_spec.js',
|
'course_bookmarks/js/spec/bookmarks_list_view_spec.js',
|
||||||
'course_bookmarks/js/spec/course_bookmarks_factory_spec.js',
|
'course_bookmarks/js/spec/course_bookmarks_factory_spec.js',
|
||||||
|
'course_search/js/spec/search_spec.js',
|
||||||
'discussion/js/spec/discussion_board_factory_spec.js',
|
'discussion/js/spec/discussion_board_factory_spec.js',
|
||||||
'discussion/js/spec/discussion_profile_page_factory_spec.js',
|
'discussion/js/spec/discussion_profile_page_factory_spec.js',
|
||||||
'discussion/js/spec/discussion_board_view_spec.js',
|
'discussion/js/spec/discussion_board_view_spec.js',
|
||||||
@@ -749,7 +750,6 @@
|
|||||||
'js/spec/markdown_editor_spec.js',
|
'js/spec/markdown_editor_spec.js',
|
||||||
'js/spec/dateutil_factory_spec.js',
|
'js/spec/dateutil_factory_spec.js',
|
||||||
'js/spec/navigation_spec.js',
|
'js/spec/navigation_spec.js',
|
||||||
'js/spec/search/search_spec.js',
|
|
||||||
'js/spec/shoppingcart/shoppingcart_spec.js',
|
'js/spec/shoppingcart/shoppingcart_spec.js',
|
||||||
'js/spec/staff_debug_actions_spec.js',
|
'js/spec/staff_debug_actions_spec.js',
|
||||||
'js/spec/student_account/access_spec.js',
|
'js/spec/student_account/access_spec.js',
|
||||||
|
|||||||
@@ -37,14 +37,6 @@ from openedx.features.course_experience import course_home_page_title, UNIFIED_C
|
|||||||
</script>
|
</script>
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
% if settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH'):
|
|
||||||
% for template_name in ["course_search_item", "course_search_results", "search_loading", "search_error"]:
|
|
||||||
<script type="text/template" id="${template_name}-tpl">
|
|
||||||
<%static:include path="search/${template_name}.underscore" />
|
|
||||||
</script>
|
|
||||||
% endfor
|
|
||||||
% endif
|
|
||||||
|
|
||||||
% if include_special_exams is not UNDEFINED and include_special_exams:
|
% if include_special_exams is not UNDEFINED and include_special_exams:
|
||||||
% for template_name in ["proctored-exam-status"]:
|
% for template_name in ["proctored-exam-status"]:
|
||||||
<script type="text/template" id="${template_name}-tpl">
|
<script type="text/template" id="${template_name}-tpl">
|
||||||
@@ -81,7 +73,7 @@ from openedx.features.course_experience import course_home_page_title, UNIFIED_C
|
|||||||
<%include file="/mathjax_include.html" args="disable_fast_preview=True"/>
|
<%include file="/mathjax_include.html" args="disable_fast_preview=True"/>
|
||||||
|
|
||||||
% if settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH'):
|
% if settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH'):
|
||||||
<%static:require_module module_name="js/search/course/course_search_factory" class_name="CourseSearchFactory">
|
<%static:require_module module_name="course_search/js/course_search_factory" class_name="CourseSearchFactory">
|
||||||
var courseId = $('.courseware-results').data('courseId');
|
var courseId = $('.courseware-results').data('courseId');
|
||||||
CourseSearchFactory(courseId);
|
CourseSearchFactory(courseId);
|
||||||
</%static:require_module>
|
</%static:require_module>
|
||||||
|
|||||||
@@ -28,12 +28,6 @@ from openedx.core.djangolib.markup import HTML, Text
|
|||||||
<%static:include path="dashboard/${template_name}.underscore" />
|
<%static:include path="dashboard/${template_name}.underscore" />
|
||||||
</script>
|
</script>
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
% for template_name in ["dashboard_search_item", "dashboard_search_results", "search_loading", "search_error"]:
|
|
||||||
<script type="text/template" id="${template_name}-tpl">
|
|
||||||
<%static:include path="search/${template_name}.underscore" />
|
|
||||||
</script>
|
|
||||||
% endfor
|
|
||||||
</%block>
|
</%block>
|
||||||
|
|
||||||
<%block name="js_extra">
|
<%block name="js_extra">
|
||||||
@@ -49,7 +43,7 @@ from openedx.core.djangolib.markup import HTML, Text
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
|
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
|
||||||
<%static:require_module module_name="js/search/dashboard/dashboard_search_factory" class_name="DashboardSearchFactory">
|
<%static:require_module module_name="course_search/js/dashboard/dashboard_search_factory" class_name="DashboardSearchFactory">
|
||||||
DashboardSearchFactory();
|
DashboardSearchFactory();
|
||||||
</%static:require_module>
|
</%static:require_module>
|
||||||
% endif
|
% endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Defines URLs for the course experience.
|
Defines URLs for course bookmarks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
define([
|
'use strict';
|
||||||
'backbone',
|
|
||||||
'js/search/base/models/search_result'
|
|
||||||
], function(Backbone, SearchResult) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'course_search/js/models/search_result'
|
||||||
|
], function(_, Backbone, SearchResult) {
|
||||||
return Backbone.Collection.extend({
|
return Backbone.Collection.extend({
|
||||||
|
|
||||||
model: SearchResult,
|
model: SearchResult,
|
||||||
@@ -26,7 +27,9 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
performSearch: function(searchTerm) {
|
performSearch: function(searchTerm) {
|
||||||
this.fetchXhr && this.fetchXhr.abort();
|
if (this.fetchXhr) {
|
||||||
|
this.fetchXhr.abort();
|
||||||
|
}
|
||||||
this.searchTerm = searchTerm || '';
|
this.searchTerm = searchTerm || '';
|
||||||
this.resetState();
|
this.resetState();
|
||||||
this.fetchXhr = this.fetch({
|
this.fetchXhr = this.fetch({
|
||||||
@@ -36,17 +39,19 @@
|
|||||||
page_index: 0
|
page_index: 0
|
||||||
},
|
},
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
success: function(self, xhr) {
|
success: function(self) {
|
||||||
self.trigger('search');
|
self.trigger('search');
|
||||||
},
|
},
|
||||||
error: function(self, xhr) {
|
error: function(self) {
|
||||||
self.trigger('error');
|
self.trigger('error');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
loadNextPage: function() {
|
loadNextPage: function() {
|
||||||
this.fetchXhr && this.fetchXhr.abort();
|
if (this.fetchXhr) {
|
||||||
|
this.fetchXhr.abort();
|
||||||
|
}
|
||||||
this.fetchXhr = this.fetch({
|
this.fetchXhr = this.fetch({
|
||||||
data: {
|
data: {
|
||||||
search_string: this.searchTerm,
|
search_string: this.searchTerm,
|
||||||
@@ -54,11 +59,11 @@
|
|||||||
page_index: this.page + 1
|
page_index: this.page + 1
|
||||||
},
|
},
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
success: function(self, xhr) {
|
success: function(self) {
|
||||||
self.page += 1;
|
self.page += 1; // eslint-disable-line no-param-reassign
|
||||||
self.trigger('next');
|
self.trigger('next');
|
||||||
},
|
},
|
||||||
error: function(self, xhr) {
|
error: function(self) {
|
||||||
self.trigger('error');
|
self.trigger('error');
|
||||||
},
|
},
|
||||||
add: true,
|
add: true,
|
||||||
@@ -68,7 +73,9 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
cancelSearch: function() {
|
cancelSearch: function() {
|
||||||
this.fetchXhr && this.fetchXhr.abort();
|
if (this.fetchXhr) {
|
||||||
|
this.fetchXhr.abort();
|
||||||
|
}
|
||||||
this.resetState();
|
this.resetState();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -101,4 +108,4 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
define(['backbone', 'js/search/base/routers/search_router', 'js/search/course/views/search_form',
|
define([
|
||||||
'js/search/base/collections/search_collection', 'js/search/course/views/search_results_view'],
|
'underscore', 'backbone', 'course_search/js/search_router', 'course_search/js/views/search_form',
|
||||||
function(Backbone, SearchRouter, CourseSearchForm, SearchCollection, SearchResultsView) {
|
'course_search/js/collections/search_collection', 'course_search/js/views/course_search_results_view'
|
||||||
|
],
|
||||||
|
function(_, Backbone, SearchRouter, CourseSearchForm, SearchCollection, CourseSearchResultsView) {
|
||||||
return function(courseId) {
|
return function(courseId) {
|
||||||
var router = new SearchRouter();
|
var router = new SearchRouter();
|
||||||
var form = new CourseSearchForm();
|
var form = new CourseSearchForm();
|
||||||
var collection = new SearchCollection([], {courseId: courseId});
|
var collection = new SearchCollection([], {courseId: courseId});
|
||||||
var results = new SearchResultsView({collection: collection});
|
var results = new CourseSearchResultsView({collection: collection});
|
||||||
var dispatcher = _.clone(Backbone.Events);
|
var dispatcher = _.clone(Backbone.Events);
|
||||||
|
|
||||||
dispatcher.listenTo(router, 'search', function(query) {
|
dispatcher.listenTo(router, 'search', function(query) {
|
||||||
@@ -44,4 +46,4 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
define(['backbone', 'js/search/base/routers/search_router', 'js/search/dashboard/views/search_form',
|
define([
|
||||||
'js/search/base/collections/search_collection', 'js/search/dashboard/views/search_results_view'],
|
'underscore', 'backbone', 'course_search/js/search_router', 'course_search/js/views/search_form',
|
||||||
function(Backbone, SearchRouter, SearchForm, SearchCollection, SearchListView) {
|
'course_search/js/collections/search_collection', 'course_search/js/views/dashboard_search_results_view'
|
||||||
|
],
|
||||||
|
function(_, Backbone, SearchRouter, SearchForm, SearchCollection, SearchListView) {
|
||||||
return function() {
|
return function() {
|
||||||
var router = new SearchRouter();
|
var router = new SearchRouter();
|
||||||
var form = new SearchForm();
|
var form = new SearchForm({
|
||||||
|
el: $('#dashboard-search-bar')
|
||||||
|
});
|
||||||
var collection = new SearchCollection([]);
|
var collection = new SearchCollection([]);
|
||||||
var results = new SearchListView({collection: collection});
|
var results = new SearchListView({collection: collection});
|
||||||
var dispatcher = _.clone(Backbone.Events);
|
var dispatcher = _.clone(Backbone.Events);
|
||||||
@@ -48,4 +52,4 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
define(['backbone'], function(Backbone) {
|
'use strict';
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
define(['backbone'], function(Backbone) {
|
||||||
return Backbone.Model.extend({
|
return Backbone.Model.extend({
|
||||||
defaults: {
|
defaults: {
|
||||||
location: [],
|
location: [],
|
||||||
@@ -11,4 +11,4 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
define(['backbone'], function(Backbone) {
|
'use strict';
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
define(['backbone'], function(Backbone) {
|
||||||
return Backbone.Router.extend({
|
return Backbone.Router.extend({
|
||||||
routes: {
|
routes: {
|
||||||
'search/:query': 'search'
|
'search/:query': 'search'
|
||||||
@@ -11,4 +11,4 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -5,17 +5,16 @@ define([
|
|||||||
'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
|
'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
|
||||||
'common/js/spec_helpers/page_helpers',
|
'common/js/spec_helpers/page_helpers',
|
||||||
'common/js/spec_helpers/template_helpers',
|
'common/js/spec_helpers/template_helpers',
|
||||||
'js/search/base/models/search_result',
|
'course_search/js/models/search_result',
|
||||||
'js/search/base/collections/search_collection',
|
'course_search/js/collections/search_collection',
|
||||||
'js/search/base/routers/search_router',
|
'course_search/js/search_router',
|
||||||
'js/search/course/views/search_item_view',
|
'course_search/js/views/search_form',
|
||||||
'js/search/dashboard/views/search_item_view',
|
'course_search/js/views/search_item_view',
|
||||||
'js/search/course/views/search_form',
|
'course_search/js/views/course_search_results_view',
|
||||||
'js/search/dashboard/views/search_form',
|
'course_search/js/views/dashboard_search_results_view',
|
||||||
'js/search/course/views/search_results_view',
|
'course_search/js/course_search_factory',
|
||||||
'js/search/dashboard/views/search_results_view',
|
'course_search/js/dashboard_search_factory',
|
||||||
'js/search/course/course_search_factory',
|
'text!course_search/templates/course_search_item.underscore'
|
||||||
'js/search/dashboard/dashboard_search_factory'
|
|
||||||
], function(
|
], function(
|
||||||
$,
|
$,
|
||||||
Backbone,
|
Backbone,
|
||||||
@@ -26,14 +25,13 @@ define([
|
|||||||
SearchResult,
|
SearchResult,
|
||||||
SearchCollection,
|
SearchCollection,
|
||||||
SearchRouter,
|
SearchRouter,
|
||||||
CourseSearchItemView,
|
SearchForm,
|
||||||
DashSearchItemView,
|
SearchItemView,
|
||||||
CourseSearchForm,
|
|
||||||
DashSearchForm,
|
|
||||||
CourseSearchResultsView,
|
CourseSearchResultsView,
|
||||||
DashSearchResultsView,
|
DashSearchResultsView,
|
||||||
CourseSearchFactory,
|
CourseSearchFactory,
|
||||||
DashboardSearchFactory
|
DashboardSearchFactory,
|
||||||
|
courseSearchItemTemplate
|
||||||
) {
|
) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@@ -86,7 +84,6 @@ define([
|
|||||||
|
|
||||||
it('sends a request and parses the json result', function() {
|
it('sends a request and parses the json result', function() {
|
||||||
var requests = AjaxHelpers.requests(this);
|
var requests = AjaxHelpers.requests(this);
|
||||||
this.collection.performSearch('search string');
|
|
||||||
var response = {
|
var response = {
|
||||||
total: 2,
|
total: 2,
|
||||||
access_denied_count: 1,
|
access_denied_count: 1,
|
||||||
@@ -99,6 +96,7 @@ define([
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
this.collection.performSearch('search string');
|
||||||
AjaxHelpers.respondWithJson(requests, response);
|
AjaxHelpers.respondWithJson(requests, response);
|
||||||
|
|
||||||
expect(this.onSearch).toHaveBeenCalled();
|
expect(this.onSearch).toHaveBeenCalled();
|
||||||
@@ -221,12 +219,7 @@ define([
|
|||||||
|
|
||||||
|
|
||||||
describe('SearchItemView', function() {
|
describe('SearchItemView', function() {
|
||||||
function beforeEachHelper(SearchItemView) {
|
beforeEach(function() {
|
||||||
TemplateHelpers.installTemplates([
|
|
||||||
'templates/search/course_search_item',
|
|
||||||
'templates/search/dashboard_search_item'
|
|
||||||
]);
|
|
||||||
|
|
||||||
this.model = new SearchResult({
|
this.model = new SearchResult({
|
||||||
location: ['section', 'subsection', 'unit'],
|
location: ['section', 'subsection', 'unit'],
|
||||||
content_type: 'Video',
|
content_type: 'Video',
|
||||||
@@ -243,31 +236,37 @@ define([
|
|||||||
url: 'path/to/content'
|
url: 'path/to/content'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.item = new SearchItemView({model: this.model});
|
this.item = new SearchItemView({
|
||||||
|
model: this.model,
|
||||||
|
template: courseSearchItemTemplate
|
||||||
|
});
|
||||||
this.item.render();
|
this.item.render();
|
||||||
this.seqItem = new SearchItemView({model: this.seqModel});
|
this.seqItem = new SearchItemView({
|
||||||
|
model: this.seqModel,
|
||||||
|
template: courseSearchItemTemplate
|
||||||
|
});
|
||||||
this.seqItem.render();
|
this.seqItem.render();
|
||||||
}
|
});
|
||||||
|
|
||||||
function rendersItem() {
|
it('rendersItem', function() {
|
||||||
expect(this.item.$el).toHaveAttr('role', 'region');
|
expect(this.item.$el).toHaveAttr('role', 'region');
|
||||||
expect(this.item.$el).toHaveAttr('aria-label', 'search result');
|
expect(this.item.$el).toHaveAttr('aria-label', 'search result');
|
||||||
expect(this.item.$el).toContainElement('a[href="' + this.model.get('url') + '"]');
|
expect(this.item.$el).toContainElement('a[href="' + this.model.get('url') + '"]');
|
||||||
expect(this.item.$el.find('.result-type')).toContainHtml(this.model.get('content_type'));
|
expect(this.item.$el.find('.result-type')).toContainHtml(this.model.get('content_type'));
|
||||||
expect(this.item.$el.find('.result-excerpt')).toContainHtml(this.model.get('excerpt'));
|
expect(this.item.$el.find('.result-excerpt')).toContainHtml(this.model.get('excerpt'));
|
||||||
expect(this.item.$el.find('.result-location')).toContainHtml('section ▸ subsection ▸ unit');
|
expect(this.item.$el.find('.result-location')).toContainHtml('section ▸ subsection ▸ unit');
|
||||||
}
|
});
|
||||||
|
|
||||||
function rendersSequentialItem() {
|
it('rendersSequentialItem', function() {
|
||||||
expect(this.seqItem.$el).toHaveAttr('role', 'region');
|
expect(this.seqItem.$el).toHaveAttr('role', 'region');
|
||||||
expect(this.seqItem.$el).toHaveAttr('aria-label', 'search result');
|
expect(this.seqItem.$el).toHaveAttr('aria-label', 'search result');
|
||||||
expect(this.seqItem.$el).toContainElement('a[href="' + this.seqModel.get('url') + '"]');
|
expect(this.seqItem.$el).toContainElement('a[href="' + this.seqModel.get('url') + '"]');
|
||||||
expect(this.seqItem.$el.find('.result-type')).toBeEmpty();
|
expect(this.seqItem.$el.find('.result-type')).toBeEmpty();
|
||||||
expect(this.seqItem.$el.find('.result-excerpt')).toBeEmpty();
|
expect(this.seqItem.$el.find('.result-excerpt')).toBeEmpty();
|
||||||
expect(this.seqItem.$el.find('.result-location')).toContainHtml('section ▸ subsection');
|
expect(this.seqItem.$el.find('.result-location')).toContainHtml('section ▸ subsection');
|
||||||
}
|
});
|
||||||
|
|
||||||
function logsSearchItemViewEvent() {
|
it('logsSearchItemViewEvent', function() {
|
||||||
this.model.collection = new SearchCollection([this.model], {course_id: 'edx101'});
|
this.model.collection = new SearchCollection([this.model], {course_id: 'edx101'});
|
||||||
this.item.render();
|
this.item.render();
|
||||||
// Mock the redirect call
|
// Mock the redirect call
|
||||||
@@ -277,27 +276,6 @@ define([
|
|||||||
expect(this.item.redirect).toHaveBeenCalled();
|
expect(this.item.redirect).toHaveBeenCalled();
|
||||||
this.item.$el.trigger('click');
|
this.item.$el.trigger('click');
|
||||||
expect(this.item.redirect).toHaveBeenCalled();
|
expect(this.item.redirect).toHaveBeenCalled();
|
||||||
}
|
|
||||||
|
|
||||||
describe('CourseSearchItemView', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
beforeEachHelper.call(this, CourseSearchItemView);
|
|
||||||
});
|
|
||||||
it('renders items correctly', rendersItem);
|
|
||||||
it('renders Sequence items correctly', rendersSequentialItem);
|
|
||||||
it('logs view event', logsSearchItemViewEvent);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DashSearchItemView', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
beforeEachHelper.call(this, DashSearchItemView);
|
|
||||||
});
|
|
||||||
it('renders items correctly', rendersItem);
|
|
||||||
it('renders Sequence items correctly', rendersSequentialItem);
|
|
||||||
it('displays course name in breadcrumbs', function() {
|
|
||||||
expect(this.seqItem.$el.find('.result-course-name')).toContainHtml(this.model.get('course_name'));
|
|
||||||
});
|
|
||||||
it('logs view event', logsSearchItemViewEvent);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -315,7 +293,7 @@ define([
|
|||||||
$('.search-field').val(term);
|
$('.search-field').val(term);
|
||||||
this.form.doSearch(term);
|
this.form.doSearch(term);
|
||||||
expect(this.onSearch).toHaveBeenCalledWith($.trim(term));
|
expect(this.onSearch).toHaveBeenCalledWith($.trim(term));
|
||||||
expect($('.search-field').val()).toEqual(term);
|
expect($('.search-field').val()).toEqual(term.trim());
|
||||||
expect($('.search-field')).toHaveClass('is-active');
|
expect($('.search-field')).toHaveClass('is-active');
|
||||||
expect($('.search-button')).toBeHidden();
|
expect($('.search-button')).toBeHidden();
|
||||||
expect($('.cancel-button')).toBeVisible();
|
expect($('.cancel-button')).toBeVisible();
|
||||||
@@ -350,26 +328,12 @@ define([
|
|||||||
expect($('.search-button')).toBeVisible();
|
expect($('.search-button')).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('CourseSearchForm', function() {
|
describe('SearchForm', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
loadFixtures('js/fixtures/search/course_search_form.html');
|
loadFixtures('course_search/fixtures/course_search_form.html');
|
||||||
this.form = new CourseSearchForm();
|
this.form = new SearchForm({
|
||||||
this.onClear = jasmine.createSpy('onClear');
|
el: '#courseware-search-bar'
|
||||||
this.onSearch = jasmine.createSpy('onSearch');
|
});
|
||||||
this.form.on('clear', this.onClear);
|
|
||||||
this.form.on('search', this.onSearch);
|
|
||||||
});
|
|
||||||
it('trims input string', trimsInputString);
|
|
||||||
it('handles calls to doSearch', doesSearch);
|
|
||||||
it('triggers a search event and changes to active state', triggersSearchEvent);
|
|
||||||
it('clears search when clicking on cancel button', clearsSearchOnCancel);
|
|
||||||
it('clears search when search box is empty', clearsSearchOnEmpty);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DashSearchForm', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
loadFixtures('js/fixtures/search/dashboard_search_form.html');
|
|
||||||
this.form = new DashSearchForm();
|
|
||||||
this.onClear = jasmine.createSpy('onClear');
|
this.onClear = jasmine.createSpy('onClear');
|
||||||
this.onSearch = jasmine.createSpy('onSearch');
|
this.onSearch = jasmine.createSpy('onSearch');
|
||||||
this.form.on('clear', this.onClear);
|
this.form.on('clear', this.onClear);
|
||||||
@@ -401,7 +365,9 @@ define([
|
|||||||
|
|
||||||
function returnsToContent() {
|
function returnsToContent() {
|
||||||
this.resultsView.clear();
|
this.resultsView.clear();
|
||||||
expect(this.resultsView.$contentElement).toHaveCss({'display': this.contentElementDisplayValue});
|
expect(this.resultsView.$contentElement).toHaveCss({
|
||||||
|
display: this.contentElementDisplayValue
|
||||||
|
});
|
||||||
expect(this.resultsView.$el).toBeHidden();
|
expect(this.resultsView.$el).toBeHidden();
|
||||||
expect(this.resultsView.$el).toBeEmpty();
|
expect(this.resultsView.$el).toBeEmpty();
|
||||||
}
|
}
|
||||||
@@ -467,28 +433,14 @@ define([
|
|||||||
expect(this.resultsView.$el.find('a.search-load-next .icon')).toBeHidden();
|
expect(this.resultsView.$el.find('a.search-load-next .icon')).toBeHidden();
|
||||||
this.resultsView.loadNext();
|
this.resultsView.loadNext();
|
||||||
// toBeVisible does not work with inline
|
// toBeVisible does not work with inline
|
||||||
expect(this.resultsView.$el.find('a.search-load-next .icon')).toHaveCss({'display': 'inline'});
|
expect(this.resultsView.$el.find('a.search-load-next .icon')).toHaveCss({
|
||||||
|
display: 'inline'
|
||||||
|
});
|
||||||
this.resultsView.renderNext();
|
this.resultsView.renderNext();
|
||||||
expect(this.resultsView.$el.find('a.search-load-next .icon')).toBeHidden();
|
expect(this.resultsView.$el.find('a.search-load-next .icon')).toBeHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
function beforeEachHelper(SearchResultsView) {
|
function beforeEachHelper(SearchResultsView) {
|
||||||
appendSetFixtures(
|
|
||||||
'<div class="courseware-results"></div>' +
|
|
||||||
'<section id="course-content"></section>' +
|
|
||||||
'<section id="dashboard-search-results"></section>' +
|
|
||||||
'<section id="my-courses" tabindex="-1"></section>'
|
|
||||||
);
|
|
||||||
|
|
||||||
TemplateHelpers.installTemplates([
|
|
||||||
'templates/search/course_search_item',
|
|
||||||
'templates/search/dashboard_search_item',
|
|
||||||
'templates/search/course_search_results',
|
|
||||||
'templates/search/dashboard_search_results',
|
|
||||||
'templates/search/search_loading',
|
|
||||||
'templates/search/search_error'
|
|
||||||
]);
|
|
||||||
|
|
||||||
var MockCollection = Backbone.Collection.extend({
|
var MockCollection = Backbone.Collection.extend({
|
||||||
hasNextPage: function() {},
|
hasNextPage: function() {},
|
||||||
latestModelsCount: 0,
|
latestModelsCount: 0,
|
||||||
@@ -497,6 +449,14 @@ define([
|
|||||||
return SearchCollection.prototype.latestModels.apply(this, arguments);
|
return SearchCollection.prototype.latestModels.apply(this, arguments);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
appendSetFixtures(
|
||||||
|
'<div class="courseware-results"></div>' +
|
||||||
|
'<section id="course-content"></section>' +
|
||||||
|
'<section id="dashboard-search-results"></section>' +
|
||||||
|
'<section id="my-courses" tabindex="-1"></section>'
|
||||||
|
);
|
||||||
|
|
||||||
this.collection = new MockCollection();
|
this.collection = new MockCollection();
|
||||||
this.resultsView = new SearchResultsView({collection: this.collection});
|
this.resultsView = new SearchResultsView({collection: this.collection});
|
||||||
}
|
}
|
||||||
@@ -599,13 +559,13 @@ define([
|
|||||||
$('.cancel-button').trigger('click');
|
$('.cancel-button').trigger('click');
|
||||||
AjaxHelpers.skipResetRequest(requests);
|
AjaxHelpers.skipResetRequest(requests);
|
||||||
// there should be no results
|
// there should be no results
|
||||||
expect(this.$contentElement).toHaveCss({'display': this.contentElementDisplayValue});
|
expect(this.$contentElement).toHaveCss({display: this.contentElementDisplayValue});
|
||||||
expect(this.$searchResults).toBeHidden();
|
expect(this.$searchResults).toBeHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearsResults() {
|
function clearsResults() {
|
||||||
$('.cancel-button').trigger('click');
|
$('.cancel-button').trigger('click');
|
||||||
expect(this.$contentElement).toHaveCss({'display': this.contentElementDisplayValue});
|
expect(this.$contentElement).toHaveCss({display: this.contentElementDisplayValue});
|
||||||
expect(this.$searchResults).toBeHidden();
|
expect(this.$searchResults).toBeHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,13 +584,14 @@ define([
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
var body;
|
||||||
$('.search-field').val('query');
|
$('.search-field').val('query');
|
||||||
$('.search-button').trigger('click');
|
$('.search-button').trigger('click');
|
||||||
AjaxHelpers.respondWithJson(requests, response);
|
AjaxHelpers.respondWithJson(requests, response);
|
||||||
expect(this.$searchResults.find('li').length).toEqual(1);
|
expect(this.$searchResults.find('li').length).toEqual(1);
|
||||||
expect($('.search-load-next')).toBeVisible();
|
expect($('.search-load-next')).toBeVisible();
|
||||||
$('.search-load-next').trigger('click');
|
$('.search-load-next').trigger('click');
|
||||||
var body = requests[1].requestBody;
|
body = requests[1].requestBody;
|
||||||
expect(body).toContain('search_string=query');
|
expect(body).toContain('search_string=query');
|
||||||
expect(body).toContain('page_index=1');
|
expect(body).toContain('page_index=1');
|
||||||
AjaxHelpers.respondWithJson(requests, response);
|
AjaxHelpers.respondWithJson(requests, response);
|
||||||
@@ -644,27 +605,14 @@ define([
|
|||||||
expect(requests[0].requestBody).toContain('search_string=query');
|
expect(requests[0].requestBody).toContain('search_string=query');
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadTemplates() {
|
|
||||||
TemplateHelpers.installTemplates([
|
|
||||||
'templates/search/course_search_item',
|
|
||||||
'templates/search/dashboard_search_item',
|
|
||||||
'templates/search/search_loading',
|
|
||||||
'templates/search/search_error',
|
|
||||||
'templates/search/course_search_results',
|
|
||||||
'templates/search/dashboard_search_results'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('CourseSearchApp', function() {
|
describe('CourseSearchApp', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
loadFixtures('js/fixtures/search/course_search_form.html');
|
var courseId = 'a/b/c';
|
||||||
|
loadFixtures('course_search/fixtures/course_search_form.html');
|
||||||
appendSetFixtures(
|
appendSetFixtures(
|
||||||
'<div class="courseware-results"></div>' +
|
'<div class="courseware-results"></div>' +
|
||||||
'<section id="course-content"></section>'
|
'<section id="course-content"></section>'
|
||||||
);
|
);
|
||||||
loadTemplates.call(this);
|
|
||||||
|
|
||||||
var courseId = 'a/b/c';
|
|
||||||
CourseSearchFactory(courseId);
|
CourseSearchFactory(courseId);
|
||||||
spyOn(Backbone.history, 'navigate');
|
spyOn(Backbone.history, 'navigate');
|
||||||
this.$contentElement = $('#course-content');
|
this.$contentElement = $('#course-content');
|
||||||
@@ -688,12 +636,11 @@ define([
|
|||||||
|
|
||||||
describe('DashSearchApp', function() {
|
describe('DashSearchApp', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
loadFixtures('js/fixtures/search/dashboard_search_form.html');
|
loadFixtures('course_search/fixtures/dashboard_search_form.html');
|
||||||
appendSetFixtures(
|
appendSetFixtures(
|
||||||
'<section id="dashboard-search-results"></section>' +
|
'<section id="dashboard-search-results"></section>' +
|
||||||
'<section id="my-courses" tabindex="-1"></section>'
|
'<section id="my-courses" tabindex="-1"></section>'
|
||||||
);
|
);
|
||||||
loadTemplates.call(this);
|
|
||||||
DashboardSearchFactory();
|
DashboardSearchFactory();
|
||||||
|
|
||||||
spyOn(Backbone.history, 'navigate');
|
spyOn(Backbone.history, 'navigate');
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
define([
|
'use strict';
|
||||||
'js/search/base/views/search_results_view',
|
|
||||||
'js/search/course/views/search_item_view'
|
|
||||||
], function(SearchResultsView, CourseSearchItemView) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
define([
|
||||||
|
'course_search/js/views/search_results_view',
|
||||||
|
'text!course_search/templates/course_search_results.underscore',
|
||||||
|
'text!course_search/templates/course_search_item.underscore'
|
||||||
|
], function(
|
||||||
|
SearchResultsView,
|
||||||
|
courseSearchResultsTemplate,
|
||||||
|
courseSearchItemTemplate
|
||||||
|
) {
|
||||||
return SearchResultsView.extend({
|
return SearchResultsView.extend({
|
||||||
|
|
||||||
el: '.courseware-results',
|
el: '.courseware-results',
|
||||||
contentElement: '#course-content',
|
contentElement: '#course-content',
|
||||||
coursewareResultsWrapperElement: '.courseware-results-wrapper',
|
coursewareResultsWrapperElement: '.courseware-results-wrapper',
|
||||||
resultsTemplateId: '#course_search_results-tpl',
|
resultsTemplate: courseSearchResultsTemplate,
|
||||||
loadingTemplateId: '#search_loading-tpl',
|
itemTemplate: courseSearchItemTemplate,
|
||||||
errorTemplateId: '#search_error-tpl',
|
|
||||||
events: {
|
events: {
|
||||||
'click .search-load-next': 'loadNext'
|
'click .search-load-next': 'loadNext'
|
||||||
},
|
},
|
||||||
SearchItemView: CourseSearchItemView,
|
|
||||||
|
|
||||||
clear: function() {
|
clear: function() {
|
||||||
SearchResultsView.prototype.clear.call(this);
|
SearchResultsView.prototype.clear.call(this);
|
||||||
@@ -31,4 +34,4 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,22 +1,24 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'js/search/base/views/search_results_view',
|
'course_search/js/views/search_results_view',
|
||||||
'js/search/dashboard/views/search_item_view'
|
'text!course_search/templates/dashboard_search_results.underscore',
|
||||||
], function(SearchResultsView, DashSearchItemView) {
|
'text!course_search/templates/dashboard_search_item.underscore'
|
||||||
'use strict';
|
], function(
|
||||||
|
SearchResultsView,
|
||||||
|
dashboardSearchResultsTemplate,
|
||||||
|
dashboardSearchItemTemplate
|
||||||
|
) {
|
||||||
return SearchResultsView.extend({
|
return SearchResultsView.extend({
|
||||||
|
|
||||||
el: '#dashboard-search-results',
|
el: '#dashboard-search-results',
|
||||||
contentElement: '#my-courses, #profile-sidebar',
|
contentElement: '#my-courses, #profile-sidebar',
|
||||||
resultsTemplateId: '#dashboard_search_results-tpl',
|
resultsTemplate: dashboardSearchResultsTemplate,
|
||||||
loadingTemplateId: '#search_loading-tpl',
|
itemTemplate: dashboardSearchItemTemplate,
|
||||||
errorTemplateId: '#search_error-tpl',
|
|
||||||
events: {
|
events: {
|
||||||
'click .search-load-next': 'loadNext',
|
'click .search-load-next': 'loadNext',
|
||||||
'click .search-back-to-courses': 'backToCourses'
|
'click .search-back-to-courses': 'backToCourses'
|
||||||
},
|
},
|
||||||
SearchItemView: DashSearchItemView,
|
|
||||||
|
|
||||||
backToCourses: function() {
|
backToCourses: function() {
|
||||||
this.clear();
|
this.clear();
|
||||||
@@ -26,4 +28,4 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
define(['jquery', 'backbone'], function($, Backbone) {
|
'use strict';
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
define(['jquery', 'backbone'], function($, Backbone) {
|
||||||
return Backbone.View.extend({
|
return Backbone.View.extend({
|
||||||
|
|
||||||
el: '',
|
el: '',
|
||||||
@@ -22,19 +22,17 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
doSearch: function(term) {
|
doSearch: function(term) {
|
||||||
|
var trimmed;
|
||||||
if (term) {
|
if (term) {
|
||||||
this.$searchField.val(term);
|
trimmed = term.trim();
|
||||||
|
this.$searchField.val(trimmed);
|
||||||
|
} else {
|
||||||
|
trimmed = this.$searchField.val().trim();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
term = this.$searchField.val();
|
|
||||||
}
|
|
||||||
|
|
||||||
var trimmed = $.trim(term);
|
|
||||||
if (trimmed) {
|
if (trimmed) {
|
||||||
this.setActiveStyle();
|
this.setActiveStyle();
|
||||||
this.trigger('search', trimmed);
|
this.trigger('search', trimmed);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.clearSearch();
|
this.clearSearch();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -63,4 +61,4 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,40 +1,41 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'jquery',
|
'jquery',
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'gettext',
|
'gettext',
|
||||||
'logger'
|
'logger',
|
||||||
], function($, _, Backbone, gettext, Logger) {
|
'edx-ui-toolkit/js/utils/html-utils'
|
||||||
'use strict';
|
], function($, _, Backbone, gettext, Logger, HtmlUtils) {
|
||||||
|
|
||||||
return Backbone.View.extend({
|
return Backbone.View.extend({
|
||||||
|
|
||||||
tagName: 'li',
|
tagName: 'li',
|
||||||
templateId: '',
|
|
||||||
className: 'search-results-item',
|
className: 'search-results-item',
|
||||||
attributes: {
|
attributes: {
|
||||||
'role': 'region',
|
role: 'region',
|
||||||
'aria-label': 'search result'
|
'aria-label': 'search result'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'click': 'logSearchItem'
|
click: 'logSearchItem'
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function(options) {
|
||||||
this.tpl = _.template($(this.templateId).html());
|
this.template = options.template;
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var data = _.clone(this.model.attributes);
|
var data = _.clone(this.model.attributes);
|
||||||
// Drop the preview text and result type if the search term is found
|
|
||||||
// in the title/location in the course hierarchy
|
// Drop the preview text and result type if the search term is found
|
||||||
|
// in the title/location in the course hierarchy
|
||||||
if (this.model.get('content_type') === 'Sequence') {
|
if (this.model.get('content_type') === 'Sequence') {
|
||||||
data.excerpt = '';
|
data.excerpt = '';
|
||||||
data.content_type = '';
|
data.content_type = '';
|
||||||
}
|
}
|
||||||
this.$el.html(this.tpl(data));
|
HtmlUtils.setHtml(this.$el, HtmlUtils.template(this.template)(data));
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -47,7 +48,6 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
logSearchItem: function(event) {
|
logSearchItem: function(event) {
|
||||||
event.preventDefault();
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var target = this.model.id;
|
var target = this.model.id;
|
||||||
var link = this.model.get('url');
|
var link = this.model.get('url');
|
||||||
@@ -56,10 +56,13 @@
|
|||||||
var pageSize = collection.pageSize;
|
var pageSize = collection.pageSize;
|
||||||
var searchTerm = collection.searchTerm;
|
var searchTerm = collection.searchTerm;
|
||||||
var index = collection.indexOf(this.model);
|
var index = collection.indexOf(this.model);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
Logger.log('edx.course.search.result_selected', {
|
Logger.log('edx.course.search.result_selected', {
|
||||||
'search_term': searchTerm,
|
search_term: searchTerm,
|
||||||
'result_position': (page * pageSize + index),
|
result_position: (page * pageSize) + index,
|
||||||
'result_link': target
|
result_link: target
|
||||||
}).always(function() {
|
}).always(function() {
|
||||||
self.redirect(link);
|
self.redirect(link);
|
||||||
});
|
});
|
||||||
@@ -67,4 +70,4 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
@@ -1,33 +1,34 @@
|
|||||||
(function(define) {
|
(function(define) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'jquery',
|
'jquery',
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'gettext'
|
'edx-ui-toolkit/js/utils/html-utils',
|
||||||
], function($, _, Backbone, gettext) {
|
'edx-ui-toolkit/js/utils/string-utils',
|
||||||
'use strict';
|
'course_search/js/views/search_item_view',
|
||||||
|
'text!course_search/templates/search_loading.underscore',
|
||||||
|
'text!course_search/templates/search_error.underscore'
|
||||||
|
], function($, _, Backbone, HtmlUtils, StringUtils, SearchItemView, searchLoadingTemplate, searchErrorTemplate) {
|
||||||
return Backbone.View.extend({
|
return Backbone.View.extend({
|
||||||
|
|
||||||
// these should be defined by subclasses
|
// these should be defined by subclasses
|
||||||
el: '',
|
el: '',
|
||||||
contentElement: '',
|
contentElement: '',
|
||||||
resultsTemplateId: '',
|
resultsTemplate: null,
|
||||||
loadingTemplateId: '',
|
itemTemplate: null,
|
||||||
errorTemplateId: '',
|
loadingTemplate: searchLoadingTemplate,
|
||||||
|
errorTemplate: searchErrorTemplate,
|
||||||
events: {},
|
events: {},
|
||||||
spinner: '.search-load-next .icon',
|
spinner: '.search-load-next .icon',
|
||||||
SearchItemView: function() {},
|
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.$contentElement = $(this.contentElement);
|
this.$contentElement = $(this.contentElement);
|
||||||
this.resultsTemplate = _.template($(this.resultsTemplateId).html());
|
|
||||||
this.loadingTemplate = _.template($(this.loadingTemplateId).html());
|
|
||||||
this.errorTemplate = _.template($(this.errorTemplateId).html());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
this.$el.html(this.resultsTemplate({
|
HtmlUtils.setHtml(this.$el, HtmlUtils.template(this.resultsTemplate)({
|
||||||
totalCount: this.collection.totalCount,
|
totalCount: this.collection.totalCount,
|
||||||
totalCountMsg: this.totalCountMsg(),
|
totalCountMsg: this.totalCountMsg(),
|
||||||
pageSize: this.collection.pageSize,
|
pageSize: this.collection.pageSize,
|
||||||
@@ -40,10 +41,10 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderNext: function() {
|
renderNext: function() {
|
||||||
// total count may have changed
|
// total count may have changed
|
||||||
this.$el.find('.search-count').text(this.totalCountMsg());
|
this.$el.find('.search-count').text(this.totalCountMsg());
|
||||||
this.renderItems();
|
this.renderItems();
|
||||||
if (! this.collection.hasNextPage()) {
|
if (!this.collection.hasNextPage()) {
|
||||||
this.$el.find('.search-load-next').remove();
|
this.$el.find('.search-load-next').remove();
|
||||||
}
|
}
|
||||||
this.$el.find(this.spinner).hide();
|
this.$el.find(this.spinner).hide();
|
||||||
@@ -52,15 +53,20 @@
|
|||||||
renderItems: function() {
|
renderItems: function() {
|
||||||
var latest = this.collection.latestModels();
|
var latest = this.collection.latestModels();
|
||||||
var items = latest.map(function(result) {
|
var items = latest.map(function(result) {
|
||||||
var item = new this.SearchItemView({model: result});
|
var item = new SearchItemView({
|
||||||
|
model: result,
|
||||||
|
template: this.itemTemplate
|
||||||
|
});
|
||||||
return item.render().el;
|
return item.render().el;
|
||||||
}, this);
|
}, this);
|
||||||
this.$el.find('ol').append(items);
|
this.$el.find('ol').append(items);
|
||||||
},
|
},
|
||||||
|
|
||||||
totalCountMsg: function() {
|
totalCountMsg: function() {
|
||||||
var fmt = ngettext('%s result', '%s results', this.collection.totalCount);
|
var fmt = ngettext('{total_results} result', '{total_results} results', this.collection.totalCount);
|
||||||
return interpolate(fmt, [this.collection.totalCount]);
|
return StringUtils.interpolate(fmt, {
|
||||||
|
total_results: this.collection.totalCount
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function() {
|
clear: function() {
|
||||||
@@ -75,26 +81,28 @@
|
|||||||
|
|
||||||
showLoadingMessage: function() {
|
showLoadingMessage: function() {
|
||||||
this.doCleanup();
|
this.doCleanup();
|
||||||
this.$el.html(this.loadingTemplate());
|
HtmlUtils.setHtml(this.$el, HtmlUtils.template(this.loadingTemplate)());
|
||||||
this.showResults();
|
this.showResults();
|
||||||
},
|
},
|
||||||
|
|
||||||
showErrorMessage: function() {
|
showErrorMessage: function() {
|
||||||
this.$el.html(this.errorTemplate());
|
HtmlUtils.setHtml(this.$el, HtmlUtils.template(this.errorTemplate)());
|
||||||
this.showResults();
|
this.showResults();
|
||||||
},
|
},
|
||||||
|
|
||||||
doCleanup: function() {
|
doCleanup: function() {
|
||||||
// Empty any loading/error message and empty the el
|
// Empty any loading/error message and empty the el
|
||||||
// Bookmarks share the same container element, So we are doing
|
// Bookmarks share the same container element, So we are doing
|
||||||
// this to ensure that elements are in clean/initial state
|
// this to ensure that elements are in clean/initial state
|
||||||
$('#loading-message').html('');
|
$('#loading-message').html('');
|
||||||
$('#error-message').html('');
|
$('#error-message').html('');
|
||||||
this.$el.html('');
|
this.$el.html('');
|
||||||
},
|
},
|
||||||
|
|
||||||
loadNext: function(event) {
|
loadNext: function(event) {
|
||||||
event && event.preventDefault();
|
if (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
this.$el.find(this.spinner).show();
|
this.$el.find(this.spinner).show();
|
||||||
this.trigger('next');
|
this.trigger('next');
|
||||||
return false;
|
return false;
|
||||||
@@ -102,4 +110,4 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})(define || RequireJS.define);
|
}(define || RequireJS.define));
|
||||||
0
openedx/features/course_search/views/__init__.py
Normal file
0
openedx/features/course_search/views/__init__.py
Normal file
@@ -29,12 +29,6 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
|
|||||||
<%static:include path="dashboard/${template_name}.underscore" />
|
<%static:include path="dashboard/${template_name}.underscore" />
|
||||||
</script>
|
</script>
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
% for template_name in ["dashboard_search_item", "dashboard_search_results", "search_loading", "search_error"]:
|
|
||||||
<script type="text/template" id="${template_name}-tpl">
|
|
||||||
<%static:include path="search/${template_name}.underscore" />
|
|
||||||
</script>
|
|
||||||
% endfor
|
|
||||||
</%block>
|
</%block>
|
||||||
|
|
||||||
<%block name="js_extra">
|
<%block name="js_extra">
|
||||||
@@ -50,7 +44,7 @@ from openedx.core.djangoapps.theming import helpers as theming_helpers
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
|
% if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):
|
||||||
<%static:require_module module_name="js/search/dashboard/dashboard_search_factory" class_name="DashboardSearchFactory">
|
<%static:require_module module_name="course_search/js/dashboard_search_factory" class_name="DashboardSearchFactory">
|
||||||
DashboardSearchFactory();
|
DashboardSearchFactory();
|
||||||
</%static:require_module>
|
</%static:require_module>
|
||||||
% endif
|
% endif
|
||||||
|
|||||||
Reference in New Issue
Block a user