Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pagination to project list #4990

Closed
wants to merge 8 commits into from
5 changes: 5 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ <h1><span class="header-inside">Projects</span></h1>
<div id="projects-panel">
{% include noscript.html %}
</div>
<div id="pagination-controls">
<button id="prev-page" disabled>Previous</button>
<span id="page-info"></span>
<button id="next-page" disabled>Next</button>
</div>
</article>
<section id="i-maintain-a-project" class="block">
{% include after.html %}
Expand Down
160 changes: 154 additions & 6 deletions javascripts/app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// @ts-nocheck

requirejs.config({
baseUrl: 'javascripts',
paths: {
// external scripts hosted on CDN
underscore:
'//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.2/underscore-min',
jquery: '//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min',
Expand All @@ -15,13 +12,164 @@ requirejs.config({
'whatwg-fetch': '//cdn.jsdelivr.net/npm/whatwg-fetch@3.0.0/dist/fetch.umd',
},
shim: {
// chosen is not UMD-compatible, so we need to use this hook to ensure
// jquery is loaded as a prerequisite
chosen: {
deps: ['jquery'],
},
},
});

// after configuring require, load the main script
requirejs(['main']);

// Add a function to handle pagination logic
function paginateProjects(projects, page, limit) {
const offset = (page - 1) * limit;
return projects.slice(offset, offset + limit);
}

// Update the renderProjects function to render the correct page of projects
const renderProjects = function (projectService, tags, names, labels, date, page = 1, limit = 15) {
const allTags = projectService.getTags();
const projects = projectService.get(tags, names, labels, date);
const paginatedProjects = paginateProjects(projects, page, limit);

projectsPanel.html(
compiledtemplateFn({
projects: paginatedProjects,
relativeTime,
tags: allTags,
popularTags: projectService.getPopularTags(6),
selectedTags: tags,
names: projectService.getNames(),
selectedNames: names,
labels: projectService.getLabels(),
selectedLabels: labels,
})
);

date = date || 'invalid';
projectsPanel
.find(`button.radio-btn[id=${date}]`)
.addClass('radio-btn-selected');
projectsPanel
.find('select.tags-filter')
.chosen({
no_results_text: 'No tags found by that name.',
width: '95%',
})
.val(tags)
.trigger('chosen:updated')
.change(function () {
location.href = updateQueryStringParameter(
getFilterUrl(),
'tags',
encodeURIComponent($(this).val() || '')
);
});

projectsPanel
.find('select.names-filter')
.chosen({
search_contains: true,
no_results_text: 'No project found by that name.',
width: '95%',
})
.val(names)
.trigger('chosen:updated')
.change(function () {
location.href = updateQueryStringParameter(
getFilterUrl(),
'names',
encodeURIComponent($(this).val() || '')
);
});

projectsPanel.find('button.radio-btn').each(function () {
$(this).click(function () {
let { id } = this;
const currentSelected = projectsPanel.find(
'button.radio-btn-selected'
)[0];

if (currentSelected && currentSelected.id == id) {
id = '';
}

location.href = updateQueryStringParameter(
getFilterUrl(),
'date',
encodeURIComponent(id || '')
);
});
});

projectsPanel
.find('select.labels-filter')
.chosen({
no_results_text: 'No project found by that label.',
width: '95%',
})
.val(labels)
.trigger('chosen:updated')
.change(function () {
location.href = updateQueryStringParameter(
getFilterUrl(),
'labels',
encodeURIComponent($(this).val() || '')
);
});

projectsPanel.find('ul.popular-tags li a').each((i, elem) => {
$(elem).on('click', function () {
selTags = $('.tags-filter').val() || [];
selectedTag = preparePopTagName($(this).text() || '');
if (selectedTag) {
tagID = allTags
.map((tag) => tag.name.toLowerCase())
.indexOf(selectedTag);
if (tagID !== -1) {
selTags.push(selectedTag);
location.href = updateQueryStringParameter(
getFilterUrl(),
'tags',
encodeURIComponent(selTags)
);
}
}
});
});

// Add pagination controls
const totalPages = Math.ceil(projects.length / limit);
$('#page-info').text(`Page ${page} of ${totalPages}`);
$('#prev-page').prop('disabled', page <= 1);
$('#next-page').prop('disabled', page >= totalPages);
};

// Add event listeners for pagination controls
$(document).ready(function () {
$('#prev-page').click(function () {
const currentPage = parseInt($('#page-info').text().match(/Page (\d+)/)[1]);
renderProjects(projectService, tags, names, labels, date, currentPage - 1);
});

$('#next-page').click(function () {
const currentPage = parseInt($('#page-info').text().match(/Page (\d+)/)[1]);
renderProjects(projectService, tags, names, labels, date, currentPage + 1);
});
});

// Add a function to validate pagination logic
function validatePagination(projects, page, limit) {
const totalPages = Math.ceil(projects.length / limit);
return page > 0 && page <= totalPages;
}

// Add a function to ensure buttons functionality works properly
function ensureButtonsFunctionality() {
$('#prev-page').prop('disabled', false);
$('#next-page').prop('disabled', false);
}

$(document).ready(function () {
ensureButtonsFunctionality();
});
Loading