- The
dots(.)
on the file names represent the directory hierarchy e.g.js.cms.[your_module].js
representsjs/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 insidedocuments.html
ofresources
. - 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 theindex.html
file for your section.
Last active
March 5, 2019 10:26
-
-
Save mutaimwiti/060a3da7ba2768cbd43f770357b92423 to your computer and use it in GitHub Desktop.
Updates to load cms data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great work Sir. The gist is easy to integrate and a handful.