Skip to content

Instantly share code, notes, and snippets.

@mutaimwiti
Last active March 5, 2019 10:26
Show Gist options
  • Save mutaimwiti/060a3da7ba2768cbd43f770357b92423 to your computer and use it in GitHub Desktop.
Save mutaimwiti/060a3da7ba2768cbd43f770357b92423 to your computer and use it in GitHub Desktop.
Updates to load cms data
cmsLoad = function () {
registerEventHandlers();
fetchDocs();
};
function registerEventHandlers() {
const searchForm = $('#docs_search_form');
const searchInput = $('#docs_input');
searchInput.keyup(function () {
const search = searchInput.val();
if (!search) {
fetchDocs(1, search);
}
});
searchForm.submit(function (event) {
event.preventDefault();
const search = searchInput.val();
if (search) {
fetchDocs(1, search);
}
})
}
function fetchDocs(page = 1, search = '') {
const params = formatObjectToParams({page: page, title: search});
client(`resources/repository/document?${params}`)
.then((res) => {
res.json().then((res) => {
render(res.data);
scrollToTop();
}).catch((err) => console.log(err));
})
}
function render(data) {
renderDocuments(data.documents);
renderPagination(data.pagination);
scrollToTop();
}
function renderDocuments(documents) {
let docs = '';
if (documents && documents.length) {
documents && documents.forEach((doc) => {
docs += `<div class="research-content__card">
<div class="research-content__details">
<p class="research-content__essentials">${doc.title}</p>
<p class="research-content__date-published">Published: ${formatDate(new Date(doc.created_at))}</p>
</div>
<div class="research-content__downloading">
<a href='${doc.document.url}' target="_blank" download><span class="research-content__download">Download</span></a>
</div>
<div class="row research-content__devider">
<hr class="content-devider">
</div>
</div>`;
});
} else {
docs =
`<div class="card-panel red lighten-5 pagination__no-results">
There are no results to display.
</div>`
}
$('#docs_docs').html(docs);
}
function renderPagination(pagination) {
const {total, totalPages, currentPage, previous, next} = pagination;
let markup = !total || totalPages === 1 ? '' :
`<div class="research-content__pagination">
<div class="pagination__page">Page</div>
<div class="current-page square-shape">${currentPage}</div>
<div class="pagination__total-items">
of <span class="available_pages">${totalPages}</span>
</div>
<a href="#documents" onclick="fetchDocs(${previous})">
<div class="previous-button square-shape ${previous ? '' : 'very-pale'}">
<i class="material-icons">navigate_before</i>
</div>
</a>
<a href="#documents" onclick="fetchDocs(${next})">
<div class="next-button square-shape ${next ? '' : 'very-pale'}">
<i class="material-icons">navigate_next</i>
</div>
</a>
</div>`;
$('#docs_pagination').html(markup);
}
const baseUrl = "http://0.0.0.0:3000/api/v1";
/**
* Client wrapper to make CMS calls.
*
* @param url
* @returns {Promise<Response>}
*/
function client(url) {
return fetch(`${baseUrl}/${url}`, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
}
/**
* Format date to natch mock up format.
*
* @param date
* @returns {string}
*/
function formatDate(date) {
return date.toDateString()
}
/**
* Extract url parameters from an object
* params {Object} params
*/
function formatObjectToParams(params) {
let url = '';
if (typeof params === 'object') {
if (Object.keys(params).length >= 1) {
Object.keys(params).forEach((key) => {
url += `${key}=${params[key]}&`;
});
// remove last &
url = url.slice(0, -1);
}
}
return url;
}
function scrollToTop() {
window.scrollTo(0, 0);
}
// PAGE SECTIONS LOADING LOGIC
/*
Call this method on your page to enable loading of content when sidebar
menu items are clicked.
*/
function enableMenuItemContentLoad() {
// ensure that when a link is clicked its content is loaded
$('.side-links a').click(function () {
loadMenuItemContent(this);
});
loadCurrentPageContent();
}
/*
Load content for the current href if an hash is set.
*/
function loadCurrentPageContent() {
if (window.location.hash) {
const selector = 'a[href="' + window.location.hash + '"]';
const item = $(selector).first();
loadMenuItemContent(item);
} else {
/*
ul for the sidebar on each pages include a data-main-link attribute
with a value equal to the window.location.pathname
*/
// get the first link to item to select respective page when no page hash is specified
const item = $('ul[data-main-link="' + window.location.pathname + '"] .side-links a').first();
if (item.length) {
loadMenuItemContent(item);
}
}
}
/*
Load content for the current sidebar menu item.
*/
function loadMenuItemContent(item) {
const link = $(item).attr('href');
if (link) {
const linkTag = link.split('#')[1];
const target = linkTag + '.html';
$('.menu-item-content').html('').load(target, execCmsLoad);
activateMenuItemLink(item, linkTag);
}
}
/*
Activate link for currently loaded sidebar item.
*/
function activateMenuItemLink(item, linkTag) {
// remove active class from list item .side-links
$('.side-links').removeClass('active');
//add active class to the selected item's parent list item .side-links
const selectedLinkLi = $(item).parent('li.side-links');
selectedLinkLi.addClass('active');
// submenu
// remove active class from submenu items
$('.collapsible-body .active').removeClass('active');
// add active class to selected submenu item
$(item).parent().closest('li').addClass('active');
/* enable active link on mobile slide-out menu also */
$('#slide-out li.side-links a[href$="' + linkTag + '"]').parent().addClass('active');
}
/*
Change header link active state dynamically
*/
function changeLinkState() {
$(".nav-wrapper ul li a").each(function (index, el) {
const pathName = el.pathname;
if (window.location.pathname.includes(pathName)) {
$(el).addClass('active');
}
});
}
/*
Executes the cmsLoad method if it has been defined. You should place all CMS logic you
need to be executed immediately after the page loads in a function named cmsLoad.
This method will be automatically triggered after the page content loads. If
your page does not make use the loadCurrentPageContent call your cmsLoad
method manually.
*/
function execCmsLoad() {
if (typeof cmsLoad === 'function') {
cmsLoad();
}
}
  • The dots(.) on the file names represent the directory hierarchy e.g. js.cms.[your_module].js represents js/cms/[your_module].js.
  • REPLACE the current js/utils.js file with the one on this gist. The changes on this file allow for synchronization of cms data loading for your module.
  • Follow the same naming convection for your module scripts. If your script belongs to a broad module create a subdirectory for the module e.g. js/cms/repository/documents.js
  • ENSURE you place the link to your script on the section to that is loaded by jquery. e.g. documents.js is imported inside documents.html of resources.
  • CREATE js/cms/utils.js and add the content on this gist. This will prevent multiple definitions of the same logic e.g. baseUrl, client wrapper, formatDate, etc.
  • ENSURE you place the link to js/cms/utils.js inside the index.html file for your section.
@p8ul
Copy link

p8ul commented Mar 5, 2019

Great work Sir. The gist is easy to integrate and a handful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment