Implementing enumeration in JavaScript

Anyone that's used a programming language like Java, C#, Swift etc has most likely made use of enumerations. Enumeration is a versatile data structure that defines a set of named values a data set can contain. The named set of values makes code easier to read and allows for some elegant solutions to problems.

For example, a days of the week enumeration data type would contain the values Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday.

Up until recently it wasn't possible to implement enumerations in JavaScript, it wasn't until JSON (JavaScript Object Notation) came along that it became possible to implement and use enumerations in a manner similar to the programming languages named in the opening sentence of this article.

So how can one implement enumeration in JavaScript? Let's use the days of the week as an example.

You could define a days of the week enumeration like this:

const weekDays = { "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 };

With the constant variable weekDays assigned the days of the week in a JSON data format we have created a rudimentary enumeration implementation that can be used in code as follows:

                        
                        
    const weekDays = { "Monday" : 0, "Tuesday" : 1, "Wednesday" : 2, "Thursday" : 3, "Friday" : 4, "Saturday" : 5, "Sunday" : 6 };

    var selectedDay = weekDays.Saturday;

    switch(selectedDay) {
        case weekDays.Monday : {
            console.log('Selected day is Monday');
            break;
        }
        case weekDays.Tuesday : {
            console.log('Selected day is Tuesday');
            break;
        }
        case weekDays.Wednesday : {
            console.log('Selected day is Wednesday');
            break;
        }
        case weekDays.Thursday : {
            console.log('Selected day is Thursday');
            break;
        }
        case weekDays.Friday : {
            console.log('Selected day is Friday');
            break;
        }
        case weekDays.Saturday : {
            console.log('Selected day is Saturday');
            break;
        }
        case weekDays.Sunday : {
            console.log('Selected day is Sunday');
            break;
        }
        default : {
            console.log('Selected day is unknown');
            break;
        }
    }                            
                        
                    

In the code above the variable selectedDay is set to weekDays.Saturday, when the switch statement runs the message 'Selected day is Saturday' is displayed in the console window as the condition case weekDays.Saturday is met.

Next we'll use enumerations in a more real life client side senario to update a web pages presentation.

Real world enumeration example

Okay lets use enumeration in a real world senario instead of presenting code snippets that at times make it hard to think of when you might apply the technique. In this example we're going to simulate a user filling out a form, before the user fills out the form they will be presented with some introductory text and when the form is completed the page will display a message that the form has been completed.

In this example the content displayed is updated without refreshing the page, click on the next button to move through the screens:

Introduction

Some introductory text goes here. Click next to continue


Click on the next button to move to the next screen and on the final screen click on the "Restart" button to reset the demonstration to the start screen.

The above example though trivial contains all the componets and mechanisms that you would find in a commercial web application and can be easily expanded to include multiple screens. Below is a listing of the html and JavaSript code of the screen example above.

The HTML

                        
                        
1.     <div class="row">
2.         <div id="form-introduction" class="col-md-9 col-xs-12">
3.             <strong>Introduction</strong>
4.             <p>Some introductory text goes here. Click next to continue</p>
5.             <button id="btnIntroduction" type="button" class="btn btn-secondary">Next</button>
6.         </div>
7.
8.         <div id="form-questions" class="col-md-9 col-xs-12" style="display: none;">
9.             <strong>Questions</strong>
10.            <p>This would be the questions page.</p>
11.            <button id="btnQuestions" type="button" class="btn btn-secondary">Next</button>
12.        </div>
13.
14.        <div id="form-complete" class="col-md-9 col-xs-12" style="display: none;">
15.            <strong>Completed</strong>
16.            <p>Display some completion message.</p>
17.            <button id="btnRestart" type="button" class="btn btn-secondary">Restart</button>
18.        </div>
19.    </div>
                        
                    

Above is the html for the example, the screens (introduction, questions and completed) are enclosed within the div tags on lines 2, 8 and 14.

The JavaScript

                        
                        

    //Variable declarations                            
    const screens = { "Introduction" : 0, "Questions" : 1, "Complete" : 2 };        //Defining the screens enumeration screens
    var currentDisplay = null;                                                      //Stores the current display that is displayed or to be displayed
    var btnIntroduction = null;                                                     //The 'Next' button on the introduction screen
    var btnQuestions = null;                                                        //The 'Next' button on the introduction screen
    var btnRestart = null;                                                          //The 'Next' button on the introduction screen
    var screenIntroduction = null;                                                  //Stores the reference to the introduction div
    var screenQuestions = null;                                                     //Stores the reference to the questions div
    var screenComplete = null;                                                      //Stores the reference to the complete div

    window.onload = initialise;                                                     //On the window load event run the function initialise

    function initialise() {                                                         //The initialise function declaration

        currentDisplay = screens.Introduction;                                      //Sets the currentDisplay variable to screens.Introduction
        btnIntroduction = document.getElementById('btnIntroduction');               //Stores a reference to the 'Next' button on the introduction page
        btnIntroduction.onclick = introductionOnClick;                              //Sets the function 'introductionOnClick' to be called on the 'onclick' even of the btnIntroduction button
        btnQuestions = document.getElementById('btnQuestions');                     //Stores a reference to the 'Next' button on the question page
        btnQuestions.onclick = questionsOnClick;                                    //Sets the function 'questionOnClick' to be called on the 'onclick' even of the btnQuestions button
        btnRestart = document.getElementById('btnRestart');                         //Stores a reference to the 'Restart' button on the completion page
        btnRestart.onclick = resetOnClick;                                          //Sets the function 'resetOnClick' to be called on the 'onclick' even of the btnRestart button

        screenIntroduction = document.getElementById('form-introduction');          //Assigns a reference to the introduction div element 
        screenQuestions = document.getElementById('form-questions');                //Assigns a reference to the introduction div element 
        screenComplete = document.getElementById('form-complete');                  //Assigns a reference to the introduction div element 

        updateDisplay();                                                            //Calls the updateDisplay function as the last action in the initialise function
    }

    //Called when the introduction 'Next' button is clicked
    function introductionOnClick() {
        setDisplay(screens.Questions);                                              //Call the setDisplay function passing 'screens.Questions' as the parameter to display the complete screen
    }

    //Called when the question 'Next' button is clicked
    function questionsOnClick() {
        setDisplay(screens.Complete);                                               //Call the setDisplay function passing 'screens.Complete' as the parameter to display the complete screen
    }

    //Called when the 'Reset' button is clicked on the completion screen
    function resetOnClick() {
        setDisplay(screens.Introduction);                                           //Call the setDisplay function passing 'screens.Introduction' as the parameter to display the complete screen
    }

    //Hides all the screen div elements on the page
    function hideAll() {
        screenIntroduction.style.display = 'none';
        screenQuestions.style.display = 'none';
        screenComplete.style.display = 'none';
    }

    function setDisplay(value) {
        currentDisplay = value;                                                     //Sets currentDisplay to value
        updateDisplay();                                                            //Calls the updateDisplay function
    }

    //Called to update the display
    function updateDisplay() {
        hideAll();                                                                  //Hides all the screen div elements by calling the hideAll function
        switch(currentDisplay) {
            case screens.Introduction : {                                           //If currentDisplay is 'screens.Introduction' execute this case
                screenIntroduction.style.display = '';                              //Display the introduction screen
                break;
            }
            case screens.Questions : {                                              //If currentDisplay is 'screens.Questions' execute this case
                screenQuestions.style.display = '';                                 //Display the questions screen
                break;
            }
            case screens.Complete : {                                               //If currentDisplay is 'screens.Complete' execute this case
                screenComplete.style.display = '';                                  //Display the complete screen
                break;
            }
            default : {
                screenIntroduction.style.display = '';
                break;
            }
        }
    }
                        
                    

The above JavaScript code has the following execution sequence:

  1. When the web page loads the initialise function is called, this function initialises variables and then ends by calling the updateDisplay function
  2. When the user first clicks on the 'Next' button the function introductionOnClick is called that calls the function setDisplay passing the parameter value 'screens.Questions'
  3. The setDisplay function sets the currentDisplay variable to the parameter value 'screens.Questions' and then calls the updateDisplay function
  4. The updateDisplay function first calls hideAll to hide all the div elements and then sets screenQuestions.style.display = '';, this action make the question screen div element appear
  5. On the questions screen when the user clicks on the 'Next' button the same sequence is repeated again as in steps 2, 3 and 4 except the complete screen is displayed as 'screens.Complete' is passed to the updateDisplay function
  6. On the completed screen when the user clicks on the 'Restart' button 'screens.Introduction' is passed to the updateDisplay function which leads to the introduction screen being displayed

Enumeration is a good way of keeping track of a users progress through a series of screens and it makes code more readable than declaring multiple variables for each value in a data set. After implementing code that makes use of enumeration you'll start to use it more often and wonder what you did before discovering this data type.

Article contents: