Setting the Groundwork
There are quite literally dozens of different approaches one could take when it comes to interaction with an FAQ page, but we want to hone in and take a close look at a particular method by which we can assist our users in finding the answer to their questions in a timely fashion. For the sake of this article, we will tackle the problem by showing all of our questions in a list and showing only the answer to the selected question when it is clicked. This gives the user complete control over only the information they would like to have access to and avoids any sort of overload. You can see an example of the technique we will be studying in use here.
Have a Pattern in Mind
You can see the structure of the markup we will be using in this article here:
As it stands, this markup will display well formed FAQs, especially with a bit of CSS applied to make it pop visually. This is precisely what we want to achieve. Now, let’s look at how to add our interaction with as minimal a footprint as possible while still allowing for scalability.
A quick glance will reveal that we can instantiate this object by passing it the ID attribute of a div (or other container) element that in turn holds all of our FAQs. When the object is created, its init() method is immediately executed, loading up the individual entries and assigning our event handlers to show and hide them as requested. We will be fleshing out those methods in a moment. Do note as well that we are storing a reference to the container object in self.holder so that we can modify or manipulate directly at any time without having to re-select that element. Now that we have our shell, we can instantiate a new FAQ object on page load that will process over the markup we previously defined.
That’s all there is to it. You can quickly see how much more manageable the code base becomes when we can minimize our footprint to this level. So, as it now stands, nothing actually happens, and interaction is what we want, so now we need to flesh out our internal methods in the FAQ object.
Processing the FAQ Markup
After looking at the shell for our FAQ object, it becomes apparent that our load method will process the markup and somehow set up our page for interaction. There are actually several things that need to be done in order for the page to display as we want:
- Individual FAQ entries must be found
- Question and answer of each entry must be recognized
- Verify there is exactly one question and answer pair for each
- Assign our click actions to the questions
Since the click action (or event listener) can be a bit complicated, we will break it out into its own method (called setupListener in the shell). Everything else can be handled fairly quickly and easily by selecting all div elements within our holder and looping over them to find those labeled as “faq-entry” items. Once those elements are identified, we find the first anchor tag and assign it as the question while assigning the first child div as our answer.
Attaching an Onclick Listener
In the load method, there is a call to setupListener that we need to flesh out now. If you examine the logic, you will see that this method is being called upon every question / answer pair, and we now simply need to code the action to perform:
Because we have been so structured in our design up to this point, the action assigned to the individual questions in incredibly simple. When a given question is clicked, we simply loop over our list of all known entries and hide each of the answers - getting us back to how our page looks at initial load time. Then, once completed, we simply target the provided answer and display it to the user, since we know it is paired with the question that was clicked. This final step of the process applies the necessary user interaction to have a fully functioning FAQ page.
Future Proofing Your Code
Planning ahead and leaving yourself some extensibility is one of the defining elements that separates good coders from those who just get by. Even if you have no plans to make future modifications to an implementation like an FAQ page, getting into the practice of always designing your code in such a way as to allow those changes, were they to arise, is a wonderful habit to form. In closing, you may review the entire code for this article in one document here: