Published: 2019-11-18 06:10 |
Category: Code | Tags: clipboard, dev, functions, javascript, professional development, update, usability
I maintain a website at school where teachers can register for professional development. They can see all offerings and save sessions to their profile for remidners, etc.
The bulk of the data comes through Javascript, which populates the main page in a fancily-styled form. Each course is a form element with a unique ID that is passed to the backend when they register. The database stores the user ID and the course ID in a couple different places to manage all the reminders.

Because each course is a JSON object, you cannot just send a link for a specific course, which is a problem when you sometimes have dozens on the screen. That means they're either having to remember to search (which matches titles) or scroll until they find the right session. Coordinating a group of people becomes difficult.
Since each of my form elements has a specific ID, I decided to use a URL query to automatically select the correct element. I can also build a specific URL for each session and add it to the element when it's built on the page. Double win. Here's how it works.
The URL
You can call window.location.search to pull any query parameters from a URL (anything after a ? character). The browser also has a handy URLSearchParams function that allows you use methods like .has() and .get() to make them more accessible in the code. With some Javascript, I can pull the keys from the URL when the page loads and then kick off another action.
I want to pass a specific course ID to the querystring for the user. So, my URL becomes:
https://mysite.com/?course=abc123
Acting on the query
The normal page load scripts didn't need to change much. I added a quick conditional to check if the URL included a query string with the .has() method I mentioned above. I can specify which key to look for, which makes extending this function easier in the future.
if (urlParams.has('course')) { // If the query matches the course being built, select the input if (urlParams.get('course') === course.key) { document.querySelector(`input[name='course'][value='${course.key}']`).checked = true; // The page can get long, so I focus the window on the specific course. window.location.hash = `#${course.key}`; // set the submit badge quantity loadSubmitBadge(); } }
If a query is passed in the URL, that course gets a checkbox pre-selected and focused on the screen for the user. They're free to either select more courses or just hit sbumit and be on their way.
Adding the link
The last step was to add a link icon to each course that could be copied and sent in an email. The course IDs are random and not easy to remember, so they needed to be provided to the users.
This was one line in the constructor:
div.querySelector('.course-share-link').href =`https://mysite.com/?course=${course.key}`
I didn't want users jumping to the link when they clicked the button, so I needed one more little function to catch that click, prevent the redirect, and then copy the URL to the clipboard for easy pasting:
async function copyToClipboard(e) { e.preventDefault(); try { await navigator.clipboard.writeText(e.target.parentNode.getAttribute('href')); alert('Workshop URL copied to clipboard'); } catch (err) { alert('Failed to copy: ', err); } }
navigator.clipboard.writeText() is a new asynchronous browser method, which is why I call await inside the try...catch block. It prevents browser errors from showing to the user.
This method should work for any HTML form as long as your form elements are unique IDs (or names) that can be targeted.