Bookmarks List Pagination

TNL-2490
This commit is contained in:
muhammad-ammar
2015-06-30 12:01:59 +05:00
committed by muzaffaryousaf
parent 4304c66c54
commit fcbe595c8a
12 changed files with 480 additions and 75 deletions

View File

@@ -1,20 +1,24 @@
;(function (define) {
'use strict';
define(['backbone', 'js/bookmarks/models/bookmark'],
function (Backbone, BookmarkModel) {
define(['backbone', 'common/js/components/collections/paging_collection', 'js/bookmarks/models/bookmark'],
function (Backbone, PagingCollection, BookmarkModel) {
return PagingCollection.extend({
initialize: function(options) {
PagingCollection.prototype.initialize.call(this);
return Backbone.Collection.extend({
model: BookmarkModel,
this.url = options.url;
this.server_api.course_id = function () { return encodeURIComponent(options.course_id); };
this.server_api.fields = function () { return encodeURIComponent('display_name,path'); };
delete this.server_api.sort_order; // Sort order is not specified for the Bookmark API
},
url: function() {
return $(".courseware-bookmarks-button").data('bookmarksApiUrl');
},
model: BookmarkModel,
parse: function(response) {
return response.results;
}
});
url: function() {
return this.url;
}
});
});
})(define || RequireJS.define);
})(define || RequireJS.define);

View File

@@ -1,7 +1,8 @@
;(function (define, undefined) {
'use strict';
define(['gettext', 'jquery', 'underscore', 'backbone', 'logger', 'moment'],
function (gettext, $, _, Backbone, Logger, _moment) {
define(['gettext', 'jquery', 'underscore', 'backbone', 'logger', 'moment',
'common/js/components/views/paging_header', 'common/js/components/views/paging_footer'],
function (gettext, $, _, Backbone, Logger, _moment, PagingHeaderView, PagingFooterView) {
var moment = _moment || window.moment;
@@ -16,27 +17,31 @@
errorMessage: gettext('An error has occurred. Please try again.'),
loadingMessage: gettext('Loading'),
PAGE_SIZE: 500,
defaultPage: 1,
events : {
'click .bookmarks-results-list-item': 'visitBookmark'
},
initialize: function (options) {
this.template = _.template($('#bookmarks_list-tpl').text());
this.template = _.template($('#bookmarks-list-tpl').text());
this.loadingMessageView = options.loadingMessageView;
this.errorMessageView = options.errorMessageView;
this.courseId = $(this.el).data('courseId');
this.langCode = $(this.el).data('langCode');
this.pagingHeaderView = new PagingHeaderView({collection: this.collection});
this.pagingFooterView = new PagingFooterView({collection: this.collection});
this.listenTo(this.collection, 'page_changed', this.render);
_.bindAll(this, 'render', 'humanFriendlyDate');
},
render: function () {
var data = {
bookmarks: this.collection.models,
bookmarksCollection: this.collection,
humanFriendlyDate: this.humanFriendlyDate
};
this.$el.html(this.template(data));
this.pagingHeaderView.setElement(this.$('.paging-header')).render();
this.pagingFooterView.setElement(this.$('.paging-footer')).render();
this.delegateEvents();
return this;
},
@@ -48,10 +53,7 @@
this.showBookmarksContainer();
this.showLoadingMessage();
this.collection.fetch({
reset: true,
data: {course_id: this.courseId, page_size: this.PAGE_SIZE, fields: 'display_name,path'}
}).done(function () {
this.collection.goTo(this.defaultPage).done(function () {
view.hideLoadingMessage();
view.render();
view.focusBookmarksElement();

View File

@@ -16,11 +16,20 @@
},
initialize: function () {
this.bookmarksListView = new BookmarksListView({
collection: new BookmarksCollection(),
loadingMessageView: new MessageView({el: $(this.loadingMessageElement)}),
errorMessageView: new MessageView({el: $(this.errorMessageElement)})
});
var bookmarksCollection = new BookmarksCollection(
{
course_id: $('.courseware-results').data('courseId'),
url: $(".courseware-bookmarks-button").data('bookmarksApiUrl')
}
);
bookmarksCollection.bootstrap();
this.bookmarksListView = new BookmarksListView(
{
collection: bookmarksCollection,
loadingMessageView: new MessageView({el: $(this.loadingMessageElement)}),
errorMessageView: new MessageView({el: $(this.errorMessageElement)})
}
);
},
toggleBookmarksListView: function () {

View File

@@ -1,5 +1,5 @@
define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'js/common_helpers/template_helpers',
'js/bookmarks/views/bookmark_button'
define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers',
'common/js/spec_helpers/template_helpers', 'js/bookmarks/views/bookmark_button'
],
function (Backbone, $, _, AjaxHelpers, TemplateHelpers, BookmarkButtonView) {
'use strict';

View File

@@ -1,20 +1,27 @@
define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_helpers',
'js/common_helpers/template_helpers', 'js/bookmarks/views/bookmarks_list_button'
],
function (Backbone, $, _, Logger, AjaxHelpers, TemplateHelpers, BookmarksListButtonView) {
define(['backbone',
'jquery',
'underscore',
'logger',
'URI',
'common/js/spec_helpers/ajax_helpers',
'common/js/spec_helpers/template_helpers',
'js/bookmarks/views/bookmarks_list_button',
'js/bookmarks/views/bookmarks_list',
'js/bookmarks/collections/bookmarks'],
function (Backbone, $, _, Logger, URI, AjaxHelpers, TemplateHelpers, BookmarksListButtonView, BookmarksListView,
BookmarksCollection) {
'use strict';
describe("lms.courseware.bookmarks", function () {
var bookmarksButtonView;
var BOOKMARKS_API_URL = '/api/bookmarks/v1/bookmarks/';
beforeEach(function () {
loadFixtures('js/fixtures/bookmarks/bookmarks.html');
TemplateHelpers.installTemplates(
[
'templates/message_view',
'templates/bookmarks/bookmarks_list'
'templates/bookmarks/bookmarks-list'
]
);
spyOn(Logger, 'log').andReturn($.Deferred().resolve());
@@ -27,12 +34,23 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
bookmarksButtonView = new BookmarksListButtonView();
});
var createBookmarksData = function (count) {
var verifyRequestParams = function (requests, params) {
var urlParams = (new URI(requests[requests.length - 1].url)).query(true);
_.each(params, function (value, key) {
expect(urlParams[key]).toBe(value);
});
};
var createBookmarksData = function (options) {
var data = {
count: options.count || 0,
num_pages: options.num_pages || 1,
current_page: options.current_page || 1,
start: options.start || 0,
results: []
};
for(var i = 0; i < count; i++) {
for(var i = 0; i < options.numBookmarksToCreate; i++) {
var bookmarkInfo = {
id: i,
display_name: 'UNIT_DISPLAY_NAME_' + i,
@@ -87,6 +105,15 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
}
};
var verifyPaginationInfo = function (requests, expectedData, currentPage, headerMessage) {
AjaxHelpers.respondWithJson(requests, expectedData);
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer span.current-page').text().trim()).
toBe(currentPage);
expect(bookmarksButtonView.bookmarksListView.$('.paging-header span').text().trim()).
toBe(headerMessage);
};
it("has correct behavior for bookmarks button", function () {
var requests = AjaxHelpers.requests(this);
@@ -101,16 +128,16 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
expect(bookmarksButtonView.toggleBookmarksListView).toHaveBeenCalled();
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveAttr('aria-pressed', 'true');
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveClass('is-active');
AjaxHelpers.respondWithJson(requests, createBookmarksData(1));
AjaxHelpers.respondWithJson(requests, createBookmarksData({numBookmarksToCreate: 1}));
bookmarksButtonView.$('.bookmarks-list-button').click();
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveAttr('aria-pressed', 'false');
expect(bookmarksButtonView.$('.bookmarks-list-button')).toHaveClass('is-inactive');
});
it("has rendered empty bookmarks list correctly", function () {
it("can correctly render an empty bookmarks list", function () {
var requests = AjaxHelpers.requests(this);
var expectedData = createBookmarksData(0);
var expectedData = createBookmarksData({numBookmarksToCreate: 0});
bookmarksButtonView.$('.bookmarks-list-button').click();
AjaxHelpers.respondWithJson(requests, expectedData);
@@ -125,25 +152,128 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
expect(bookmarksButtonView.bookmarksListView.$('.bookmarks-empty-detail-title').text().trim()).
toBe(emptyListText);
expect(bookmarksButtonView.bookmarksListView.$('.paging-header').length).toBe(0);
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer').length).toBe(0);
});
it("has rendered bookmarked list correctly", function () {
var requests = AjaxHelpers.requests(this);
var url = BOOKMARKS_API_URL + '?course_id=COURSE_ID&page_size=500&fields=display_name%2Cpath';
var expectedData = createBookmarksData(3);
var expectedData = createBookmarksData({numBookmarksToCreate: 3});
spyOn(bookmarksButtonView.bookmarksListView, 'courseId').andReturn('COURSE_ID');
bookmarksButtonView.$('.bookmarks-list-button').click();
expect($('#loading-message').text().trim()).
toBe(bookmarksButtonView.bookmarksListView.loadingMessage);
AjaxHelpers.expectRequest(requests, 'GET', url);
verifyRequestParams(
requests,
{course_id: 'a/b/c', fields: 'display_name,path', page: '1', page_size: '10'}
);
AjaxHelpers.respondWithJson(requests, expectedData);
expect(bookmarksButtonView.bookmarksListView.$('.bookmarks-results-header').text().trim()).
toBe('My Bookmarks');
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
expect(bookmarksButtonView.bookmarksListView.$('.paging-header').length).toBe(1);
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer').length).toBe(1);
});
it("calls bookmarks list render on page_changed event", function () {
var renderSpy = spyOn(BookmarksListView.prototype, 'render');
var listView = new BookmarksListView({collection: new BookmarksCollection({course_id: 'abc'})});
listView.collection.trigger('page_changed');
expect(renderSpy).toHaveBeenCalled();
});
it("can go to a page number", function () {
var requests = AjaxHelpers.requests(this);
var expectedData = createBookmarksData(
{
numBookmarksToCreate: 10,
count: 12,
num_pages: 2,
current_page: 1,
start: 0
}
);
bookmarksButtonView.$('.bookmarks-list-button').click();
AjaxHelpers.respondWithJson(requests, expectedData);
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
bookmarksButtonView.bookmarksListView.$('input#page-number-input').val('2');
bookmarksButtonView.bookmarksListView.$('input#page-number-input').trigger('change');
expectedData = createBookmarksData(
{
numBookmarksToCreate: 2,
count: 12,
num_pages: 2,
current_page: 2,
start: 10
}
);
AjaxHelpers.respondWithJson(requests, expectedData);
verifyBookmarkedData(bookmarksButtonView.bookmarksListView, expectedData);
expect(bookmarksButtonView.bookmarksListView.$('.paging-footer span.current-page').text().trim()).
toBe('2');
expect(bookmarksButtonView.bookmarksListView.$('.paging-header span').text().trim()).
toBe('Showing 11-12 out of 12 total');
});
it("can navigate forward and backward", function () {
var requests = AjaxHelpers.requests(this);
var expectedData = createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
);
bookmarksButtonView.$('.bookmarks-list-button').click();
verifyPaginationInfo(requests, expectedData, '1', 'Showing 1-10 out of 15 total');
verifyRequestParams(
requests,
{course_id: 'a/b/c', fields: 'display_name,path', page: '1', page_size: '10'}
);
bookmarksButtonView.bookmarksListView.$('.paging-footer .next-page-link').click();
expectedData = createBookmarksData(
{
numBookmarksToCreate: 5,
count: 15,
num_pages: 2,
current_page: 2,
start: 10
}
);
verifyPaginationInfo(requests, expectedData, '2', 'Showing 11-15 out of 15 total');
verifyRequestParams(
requests,
{course_id: 'a/b/c', fields: 'display_name,path', page: '2', page_size: '10'}
);
expectedData = createBookmarksData(
{
numBookmarksToCreate: 10,
count: 15,
num_pages: 2,
current_page: 1,
start: 0
}
);
bookmarksButtonView.bookmarksListView.$('.paging-footer .previous-page-link').click();
verifyPaginationInfo(requests, expectedData, '1', 'Showing 1-10 out of 15 total');
verifyRequestParams(
requests,
{course_id: 'a/b/c', fields: 'display_name,path', page: '1', page_size: '10'}
);
});
it("can navigate to correct url", function () {
@@ -151,7 +281,7 @@ define(['backbone', 'jquery', 'underscore', 'logger', 'js/common_helpers/ajax_he
spyOn(bookmarksButtonView.bookmarksListView, 'visitBookmark');
bookmarksButtonView.$('.bookmarks-list-button').click();
AjaxHelpers.respondWithJson(requests, createBookmarksData(1));
AjaxHelpers.respondWithJson(requests, createBookmarksData({numBookmarksToCreate: 1}));
bookmarksButtonView.bookmarksListView.$('.bookmarks-results-list-item').click();
var url = bookmarksButtonView.bookmarksListView.$('.bookmarks-results-list-item').attr('href');

View File

@@ -57,7 +57,7 @@
// Rules for Bookmarks Results
.bookmarks-results-list {
padding-top: $baseline;
padding-top: ($baseline/2);
.bookmarks-results-list-item {
@include padding(($baseline/4), $baseline, ($baseline/2), $baseline);
@@ -181,3 +181,9 @@ i.bookmarked {
@include icon-style("\f097", $black);
@include hover-style($m-blue, $m-blue, "\f02e");
}
.paging-header {
.search-tools {
margin: 0;
}
}

View File

@@ -1,10 +1,12 @@
<div id="my-bookmarks" class="sr-is-focusable" tabindex="-1"></div>
<h2 class="bookmarks-results-header"><%= gettext("My Bookmarks") %></h2>
<% if (bookmarks.length) { %>
<% if (bookmarksCollection.length) { %>
<div class="paging-header"></div>
<div class='bookmarks-results-list'>
<% _.each(bookmarks, function(bookmark, index) { %>
<% bookmarksCollection.each(function(bookmark, index) { %>
<a class="bookmarks-results-list-item" href="<%= bookmark.blockUrl() %>" aria-labelledby="bookmark-link-<%= index %>" data-bookmark-id="<%= bookmark.get('id') %>" data-component-type="<%= bookmark.get('block_type') %>" data-usage-id="<%= bookmark.get('usage_id') %>" aria-describedby="bookmark-type-<%= index %> bookmark-date-<%= index %>">
<div class="list-item-content">
<div class="list-item-left-section">
@@ -21,6 +23,8 @@
<% }); %>
</div>
<div class="paging-footer"></div>
<% } else {%>
<div class="bookmarks-empty" tabindex="0">

View File

@@ -53,7 +53,7 @@ ${page_title_breadcrumbs(course_name())}
% endfor
% endif
% for template_name in ["bookmarks_list"]:
% for template_name in ["bookmarks-list"]:
<script type="text/template" id="${template_name}-tpl">
<%static:include path="bookmarks/${template_name}.underscore" />
</script>