When we click an item in the sidebar we want to make that the active element (we remove the active
class from all the other elements and add it to the one just clicked).
Also, we’ll perform a fetch
request to the backend, we’ll create a simple API endpoint that returns the data as JSON, optionally filtered by site, so if we pass the site as parameter we get that filtered.
Last, we’ll update the DOM with the new data.
Let’s go!
First we intercept the click event on any sidebar item, and we assign to the active
class to the element clicked:
const sidebarLinks = document.querySelectorAll("#sidebar li")
for (const sidebarLink of sidebarLinks) {
sidebarLink.addEventListener('click', function(event) {
for (const sidebarLink of sidebarLinks) {
sidebarLink.classList.remove('active')
}
this.classList.add('active')
})
}
Then we filter the data.
We create a fetchStats()
function to ask the server that specific site data:
const fetchStats = site => {
fetch('/stats?site=' + encodeURIComponent(site)).then(response => {
//...
})
.catch(err => console.error(err))
}
We call this function in the event listener, passing the text contained in the sidebar item (referenced using textContent
):
const sidebarLinks = document.querySelectorAll("#sidebar li")
for (const sidebarLink of sidebarLinks) {
sidebarLink.addEventListener('click', function(event) {
for (const sidebarLink of sidebarLinks) {
sidebarLink.classList.remove('active')
}
this.classList.add('active')
fetchStats(this.textContent)
})
}
On the server side, we listen on the /stats
endpoint and based on the site
query parameter, we return either all the data, or we filter the data to only return a specific site data:
app.get('/stats', (req, res) => {
const site = req.query.site
if (site === 'All') {
res.json(data.sums)
return
} else {
const filteredData = data.aggregate.filter(item => item.property.name === site)
res.json(filteredData[0])
}
})
Now we need to alter the data in the DOM.
We can do it in the fetchStats()
function callback. We first parse the JSON response using
fetch('/stats?site=' + encodeURIComponent(site))
.then(response => response.json())
.then(body => {
})
and inside the last then
we can access the body values. We’ll assign them to each DOM element using innerText
:
const fetchStats = (site) => {
fetch('/stats?site=' + encodeURIComponent(site)).then(response => response.json())
.then(body => {
document.querySelector('#today .total').innerText = body.today.total
document.querySelector('#today .organic').innerText = body.today.organic
document.querySelector('#yesterday .total').innerText = body.yesterday.total
document.querySelector('#yesterday .organic').innerText = body.yesterday.organic
document.querySelector('#monthly .total').innerText = body.monthly.total
document.querySelector('#monthly .organic').innerText = body.monthly.organic
})
.catch(err => console.error(err))
}
We’re done! We can now see the values update when we click a site on the sidebar.
The full code is available at https://glitch.com/edit/#!/node-course-project-analytics-dashboard-e and the app working is at https://node-course-project-analytics-dashboard-e.glitch.me/