Skip to content

Commit

Permalink
Document event listeners and functions on main js files
Browse files Browse the repository at this point in the history
  • Loading branch information
mrchrisadams committed Jul 11, 2024
1 parent b802707 commit 6a8fe0a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 50 deletions.
89 changes: 48 additions & 41 deletions cl8/static/js/home-page.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
/**
* Add a set of event listeners to the active tag list, below the search bar
* so that clicking on them updates the selected options, and triggers a
* 'toggle-tag' event, for our form to listen for and request an uploaded
* so that clicking on them:
*
* 1. updates the selected options, and
* 2. triggers a 'toggle-tag' event, for our form to listen for and request an uploaded
* list of matching profiles
*/
function addListenersForActiveTags() {
document
.querySelectorAll('.search-block .active-tags .badge')
.forEach((item) => {
// add a listener to the badge button

// add a listener to the badge button
item.addEventListener('click', (event) => {
// find the option element in the hidden tags field
const selectorString = `#id_tags option[value="${event.target.dataset.tagId}"]`
Expand All @@ -28,8 +31,8 @@ function addListenersForActiveTags() {

// our white cross needs to be clickable too, so we add a listener to
// that to trigger the same click event
// TODO: events should bubble up the DOM. Why is it not bubbling, meanin we
// resort to this hacky behaviour?
// TODO: events should bubble up the DOM. Why is it not
// bubbling, meaning we resort to this hacky behaviour?
const closeCross = item.parentElement.querySelector('.close-cross')
closeCross.addEventListener('click', (event) => {
item.click()
Expand All @@ -46,12 +49,13 @@ function addListenersForActiveTags() {
* */
function toggleTagBadge(event) {
// we can't just bubble up a 'click' event to the parent elements
// and use that to update the list of profiles shown, because
// it won't reflect the updated toggle list of tags yet in the
// below the search input in the filter form.
// and use that to update the list of profiles shown.
//
// This is because the eventlist of tags yet below the search input
// in the filter form will remain unchanged.

// So, we have to manually update the list of active tags, and THEN
// dispatch an event for our filter component to listen for
// dispatch an event for our filter form component to listen for

// you set a value on a multiple select by setting the
//'selected' property of a given option to true
Expand All @@ -60,27 +64,33 @@ function toggleTagBadge(event) {
chosenTagOption.selected = !chosenTagOption.selected

// once we have updated the option list, we trigger
// a Custom DOM event for our filter component to listen for,
// and update the list of profiles shown.
// We pass along the id of the tag that was toggled to any other allow
// listeners to update the status of any visible tags
// a Custom DOM event for other components like our filter form to listen for.

// We pass along the id of the tag that was toggled, so any components
// with event handlers can update the status of any visible tags
document.body.dispatchEvent(
new CustomEvent('toggle-tag', { detail: event.target.dataset.tagId })
)

// finally, we make sure this badge itself has the correct colouring too
// finally, we make sure this badge itself that was clicked has the correct
// colouring too
if (chosenTagOption.selected) {
event.target.classList.add('bg-blue-500')
} else {
event.target.classList.remove('bg-blue-500')
}
}

/**
* Add a click listener to the tag badges in the profile view, so that
* clicking on them toggles the tag in the search bar, and updates the
* list of profiles shown.
* */
function addListenersForTagBadges() {
document.querySelectorAll('#profile-slot .badge').forEach((item) => {

// add a listener to the badge button for clicks if there isn't one already
if (!item.getAttribute('data-hasClickListener')) {
console.log('adding click listener')
item.addEventListener('click', toggleTagBadge)
item.setAttribute('data-hasClickListener', 'true')
}
Expand All @@ -93,16 +103,19 @@ document.addEventListener('DOMContentLoaded', (event) => {
})

/*
* Listen for the profile-tag-created event, when a user updates a entry via htmx,
* Listen for the 'profile-tag-created' event, when a user updates a entry via htmx,
* and update the list of options in the hidden tags field.
* This is needed for adding `addListenersForActiveTags`, which relies on
* having access to the id of the newly created tag
*
* This is needed when we call `addListenersForActiveTags`, which relies on
* having access to the id of the newly created tag to create an event listener on the new
* tag badge.
*/
document.body.addEventListener('profile-tag-created', function (evt) {
console.debug('profile-tag-created event triggered')
console.debug({ evt })

// create an option element with the data from the evt detail {value: '123', text: "tagname"} object:
// create an option element with the data from the evt detail
// {value: '123', text: "tagname"} object:
const newOption = document.createElement('option')
newOption.value = evt.detail.value
newOption.text = evt.detail.text
Expand All @@ -115,7 +128,8 @@ document.body.addEventListener('profile-tag-created', function (evt) {
})

/**
* Listen for the update-profile event, triggered by HTMX and update the profile view.
* Listen for the 'update-profile' event, triggered by HTMX and update the profile view.
*
* Mainly used by touch devices who only have space to either show the list of profiles
* or only show the profile view.
*/
Expand Down Expand Up @@ -159,47 +173,40 @@ document.body.addEventListener('active-tags-changed', (event) => {
})

/**
* Listen for a toggle-tag event triggered by people updating the selection
* of active tags in the search bar, or by clicking on the tag badges the main
* region of the page on a profile or the full list of tags when no profile or search
* terms are selected.
* Runs through every tag, and it is in the list of active tags, it sets them
* Listen for a toggle-tag event triggered by:
*
* 1. people updating the selection of active tags in the search bar,
* 2. by clicking on the tag badges in the main region of the page on a profile or
* 3. clicking on the full list of tags when no profile or search terms are selected
*
* Runs through every tag, and if it is in the list of active tags, it sets them
* to show as active
*
*/
document.body.addEventListener('toggle-tag', (event) => {
console.log({ event })
console.log({ detail: event.detail })

var tags = new URLSearchParams(new URL(window.location.href).search).getAll(
var tagsInUrl = new URLSearchParams(new URL(window.location.href).search).getAll(
'tags'
)
console.log({ tags })
console.log({ tagsInUrl })

if (tags.includes(event.detail)) {
if (tagsInUrl.includes(event.detail)) {
// remove the tag from tags
tags = tags.filter((tag) => tag !== event.detail)
tagsInUrl = tagsInUrl.filter((tag) => tag !== event.detail)
}
document.querySelectorAll('#profile-slot .badge').forEach((item) => {
const tagId = item.getAttribute('data-tag-id')


// if tagId is in the tag list, set the button to active
if (tags.includes(tagId)) {
if (tagsInUrl.includes(tagId)) {
item.classList.add('bg-blue-500')
} else {
item.classList.remove('bg-blue-500')
}
})
})

// get the list of tags from the URL
// TODO: we refer to this list of tags when handling the toggle-tag event
//
var tags = new URLSearchParams(new URL(window.location.href).search).getAll(
'tags'
)

// add listeners for clickable tags in the search component
addListenersForActiveTags()

// add listeners for clickable tags in home page view, or when viewing a profile
addListenersForTagBadges()
23 changes: 14 additions & 9 deletions cl8/static/js/profile-page.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
// when a user clicks on a tag, emit an event listing the name of the tag being clicked
// this is picked up by the parent component and used to filter the list of profiles
// shown


/**
* Clear the profile slot and set the path in the url back to "/",
* adding the GET params, then the url to the history
Expand All @@ -20,7 +15,11 @@ function clearProfile() {
// then set the profile slot to the empty profile
const emptyProfile = document.querySelector('#empty-profile').innerHTML
document.querySelector('#profile-slot .profile').innerHTML = emptyProfile
// the 'update-profile' profile event is mainly used on small viewports /
// touch devices
htmx.trigger("body", "update-profile")
// with the empty profile added, we need to add the click listeners
// to the listed tags again
addListenersForTagBadges()


Expand All @@ -30,19 +29,25 @@ if (document.querySelector('#clear-profile')) {
document.querySelector('#clear-profile').addEventListener('click', clearProfile)
}

// close-modal event is triggered when we have a successful update
// to a profile
// close-modal event is triggered by the server when we have a
// successful update to a profile.
// We listen for this event to close the model we just used to edit the profile
document.body.addEventListener('close-modal', function () {
const openDialog = document.querySelector('dialog[open]');

if (openDialog) {
openDialog.close();
}
// trigger a reload of the profile with a 'save-profile-change'
//event, this makes sure we have the latest info for the profile
//event. This makes sure we have the latest info for the profile
document.body.dispatchEvent(new CustomEvent("save-profile-change"))
});

/**
* We listen for the htmx:afterSettle for event know to trigger displaying of
* the profile edit modal for making edits, and when loading the profile page
* we add the listeners to the tag badges so clicking them updates our list of profiles
*/
document.body.addEventListener("htmx:afterSettle", function (detail) {
const dialog = detail.target.querySelector('dialog[data-onload-showmodal]');
if (dialog) {
Expand All @@ -54,6 +59,6 @@ document.body.addEventListener("htmx:afterSettle", function (detail) {
};
console.debug("DOM fully loaded and parsed in HTMX");

// add click listeners to the badges
// add click listeners to the badges on the profile page load
addListenersForTagBadges()
});

0 comments on commit 6a8fe0a

Please sign in to comment.