DEV Community

Cover image for How to Create a JavaScript SPA Using the MVC Architecture (Part 1)
Tarwat Uddin
Tarwat Uddin

Posted on • Edited on

How to Create a JavaScript SPA Using the MVC Architecture (Part 1)

Table of Contents: [NEW]

Creating a complex application from scratch can be a quite daunting task, and in more particular, one that requires a good grasp of knowledge of how you are able to structure such an application.

Thanks to software architectures, such as the MVC architecture, there are clear and refined ways of managing complex applications with much ease.

However, you may be still stuck and unsure of how to go about this process. No worries.

This first post, as part of a two-part post series, will cover the build cycle of such a complex application from start-to-finish. And in this post specifically I will be focusing on the design of this application from a UI/UX perspective and not the logic just yet. If you feel like this isn't relevant for your needs, then please feel free to skip to the next post in this series.

Firstly, the project that I will be working on is called "Inspiro" and is based on the theme of self-improvement. This project in a nutshell helps you to become more productive with your life and take inspiration from successful individuals.

This two-part post series will document the whole entire process of creating this complex application from scratch and pretty much everything but the non-essential parts that I think would really produce substance and value for you.

My main goal for this application is to be able to code its main, core functionalities which I would have derived from user stories, and to wrap this whole application altogether with a beautiful responsive UI.

And with that all said, we can now begin!

User Stories

  • User is able to track days they have been productive
  • User can set weekly goals to complete
  • User is able retrieve appropriate information on a person
  • User is able to add a person to their bookmarks
  • User is able to bookmark given quotes

Flowchart

Firstly, I begin working on this project by creating a somewhat simple flowchart based on user stories that I’ve declared before setting out to bring this project to fruition.

Application flowchart

TIP: I highly recommend that you create flowcharts for such complex applications because not only will this help you stay focused on what you need to implement into your application rather than getting side-tracked by minor features, it will also save you valuable time when it comes to figuring how your application should function as a whole.

App UX Design

Since this application will be responsive, I will begin by creating my application the "mobile-first" design approach since that is the way I like to start my responsive designs with, however feel free in your own projects to start with "desktop-first" in-mind if you feel that is easier for you.

Mobile user-experience design

The different features displayed on the homepage design user-interface showcase some of the different user stories compact into one single page. However, it would also be wise to create other pages to showcase the other user stories which I will be doing instead of cramming them all into one single page.

TIP: Whenever you need to plan out whether you need to, or optionally, create pages to separate the concerns of your user-stories, be sure to keep in mind how those features fit well together because if they don’t, then this can create a really bad user-experience which we of course don’t want.

Environment Setup

This project will be based on the MVC architecture so my project’s folder structure will look something like this:

dir.
|   index.html
|
\---src
    \---scripts
    |   |   controller.js
    |   |   helpers.js
    |   |   model.js
    |   |
    |   |   views
    |
    \---stylesheets
            reset.css
            style.css
Enter fullscreen mode Exit fullscreen mode

The project setup for this application is sufficient for now, and I can now begin by first focusing on coding the main HTML/CSS parts of the application before moving onto the main JavaScript part, which is the personal preference that I stick with when creating an application using only JavaScript without frameworks from scratch.

Here is a quick code snapshot of the initial HTML structure of the application:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" type="text/css" href="./src/stylesheets/reset.css" />
    <link rel="stylesheet" type="text/css" href="./src/stylesheets/style.css" />
    <title>Inspiro</title>
  </head>
  <body>
    <header class="head">
      <div class="head__content"></div>
    </header>

    <nav class="nav--menu">
      <ul class="nav__tabs"></ul>
    </nav>

    <main class="main">
      <div class="main__content content">
        <div class="content__aside aside"></div>
        <div class="content__wrapper wrapper"></div>
        <div class="container--quote"></div>
      </div>
    </main>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

TIP: If you are stuck and unsure where to start when coding the first few lines of HTML for a page, begin by breaking down the design of your webpage that you’ve created into different HTML semantic elements. Once done, add your appropriate CSS classes which will style those HTML semantic elements. I believe this all helps to give you a good grasp of the bigger picture of exactly how the flow of your application should be structured.

I will now refer to the design which I’ve created prior beginning this project so I can use it to help me build the UX design for this application.

Building the UX Design

After inserting some dummy content into my webpage and adding some basic styles, I’ve come up with this initial design of the app for mobile devices:

User-experience design for mobile devices screenshot 1

User-experience design for mobile devices screenshot 2

Keep in mind that I’m not focusing on creating a beautiful UI just yet, before I get to that stage, I need to now work on adding media queries to support device accessibility for larger devices such as tablets and laptops. This process will usually consist of looking for points in my application that start to “break” – or otherwise known as “breakpoints”.

TIP: Some data has been populated onto the app manually, but I find that this helps to visualise how the app should look like once I begin computing data into the app and therefore I will suggest for you to do likewise in your own applications.

Responsive Design

The focus here is now to add media queries to support larger devices as mentioned earlier. I’m going to wrap the main content of the page into a flex-box so that I can create the responsive fluid design layout that I’m trying to implement here. Here is the result:

Fluid responsive design

TIP: There are a few responsive design layouts patterns out there you can implement into your applications other than the one that I’m using (“Mostly Fluid”), for instance, using something like the “Layout Shifter” or “Column Drop” design layout pattern.

Single Page Application

I need to now think about how I’m going to be able to navigate the different tabs within the same page without sending a HTTP request for a HTML page from a server. This is what is known as creating a "single-page application" (SPA) aspired from mobile applications where everything is contained into one single app.

Although this first post is not focused on the implementation of the logic behind this application, I will briefly mention what I’m going to do, but I will expand further in the next post of this two-part post series so be sure to not miss that one out!

<!-- Toggle menu -->
<nav class="content__nav--menu">
  <!-- Links to different views -->
  <ul class="nav__tabs">
    <li class="tabs__item">
      <a class="item__link item__link--home" href="/">Home</a>
    </li>
    <li class="tabs__item">
      <a class="item__link item__link--quotes" href="/quotes">Quotes</a>
    </li>
    <li class="tabs__item">
      <a class="item__link item__link--models" href="/models">Role Models</a>
    </li>
  </ul>
</nav>
{ … }   
<main class="main">
  <!-- Page that display the different views -->
  <div class="main__content content—flex">{ … }</div>
</main>
Enter fullscreen mode Exit fullscreen mode

The code above shows how I’m going about this. When I click on one of the tabs in the menu it’s going to change the main content of the page according to the link that has been selected, and this is done via a router in the front-end portion of my code which will perform this and render the appropriate page.

Note: There are different approaches to implementing routing in JavaScript, however I personally think that this approach of rendering the views within the <div class="main__content content—flex"> of the page via DOM manipulation this way to be a quite a simple and easy approach.

Web Design

I know that this isn’t a post about web design, but I thought it will be beneficial to quickly distinguish the two terms that get quite often used interchangeable and seem to mean the exact same when they not – I’m talking about UI (user interface) and UX (user experience).

User interface is simply the "look and feel" of a product, or in this case, a web application. User experience is however the way the web application "works".

After learning this for the first time, I never saw web design the same way.

Anyone to get back-to-track, after completing the UX design of my application, all I need to do is now improve the UI aesthetically.

This section is not a crash course on how to create beautiful UIs but I will however suggest here a free course on Udemy that helped me come up with the design for my project right here. It’s only a 1-hour course that goes through really simple practical guidelines which you can use when thinking about the design for your applications.

To cut to the chase, here is my newly improved UI!:

Improved app user-interface

So at this point, I begin gradually improving the UI of the application by focusing now on using web-design best practises in order to create a well-made UI.

CSS custom variables are going to be my best friend when it comes to creating a consistent theme throughout my app UI since I won’t be using any frameworks.

TIP: CSS frameworks such as SASS make the process of achieving a consistent look that you desire for your applications that much easier because of the flexibility it provides so therefore I recommend to use one if you can.

/* Custom CSS properties */
:root {
  /* Primary Colors */
  --color-primary: #4b4b4b;
  --color-primary-lighter: #aeadad;
  /* Secondary Colors */
  --color-secondary: #464646;
  --color-secondary-darker: #2d2d2d;
  --color-secondary-lighter: #a2a3a1;
  /* Tertiary Colors */
  --color-tertiary: #3c3c3c;
  --color-tertiary-lighter: #8a8b8a;
  /* Font */
  --font-primary: #fff;
  --font-primary-hover: #ccc;
  --font-secondary: #000;
  /* Input */
  --input-primary: #fff;
  --input-primary-hover: #ccc;
}
Enter fullscreen mode Exit fullscreen mode

These properties can be easily changed overtime if anytime in the future I decide I want to recreate the UI of the app, all I have to do is changed these variables and thus I save time having to track every location where the property of an element I want to change, which can become an ever increasing nightmare as the CSS stylesheet gets larger over time as more styles are added.

Page Design

In these following sub-sections, I’m going to be designing my webpages.

A quick snapshot will also be provided of each of the HTML templates to give an idea of how each one looks.

TIP: When it comes to HTML templating engines, there are two types: ones that use markup formats that can be transpiled to HTML and while others use HTML to define the layout – choose the one that best suits your preference - the templating engine that I will be using is "HandleBars".

Home Page

function quotaTemplate() {
  return `
    <ul class="content__container-list">
      {{targetData targets}}
    </ul>
  `;
}

function quoteTemplate() {
  return `
    <i
    class="content__container-icon--bookmark gg-bookmark"
    title="Add to quotes"
    ></i>
    <q class="container__label container__label--quote">{{text}}</q>
    <p class="container__label container__label--author">{{author}}</p>
  `;
}

function calendarTemplate() {
  return `
    <thead>
      <tr>
        {{#each days}}
        <th class="row-header" scope="col">{{this}}</th>
        {{/each}}
      </tr>
    </thead>
    <tbody>
      {{tableData markedDays firstDayIndex prevLastDay lastDay currMonth today}}
    </tbody>
  `;
}

function calendarPaginationTemplate() {
  return `
    <button class="nav__btn nav__btn--prev btn" data-goto="{{prevMonth}}"">
      Previous
    </button>
    <button class="nav__btn nav__btn--next btn" data-goto="{{nextMonth}}">
      Next
    </button>
  `;
}
Enter fullscreen mode Exit fullscreen mode

After implementing the web-design rules as mentioned sometime earlier, I’ve came up with this beautiful UI:

Home page user-interface

Article Page

For the article page, when I retrieve the data for a query search on a specific individual, the data that I receive will need to be parsed into a format I can really play with, so that I can use that data to insert into our view.

I will be using an API provided by MediaWiki to gather the relevant information and do as mentioned prior. To be able to create a template based on the data received and need to see what the expected output will look like when I create API searches directly on the application and see what the output data I would receive.

TIP: Some API’s have a feature which allows you to create API queries and get results instantly without having to call them directly from your application, so I recommend to use such features where possible.

function articleTemplate() {
  return `
    <header class="content__head">
      <h1 class="head__header">{{title}}</h1>
      <div class="head__container-img">
        <i
        class="head__icon--bookmark gg-bookmark"
        title="Add to models"
        ></i>
        <img
          class="head__img"
          src="{{imageSrc}}"
        />
      </div>
      <ul class="head__list">
        <li class="list__item--header">
          Contents
        </li>
        {{columnData pageContents}}
      </ul>
    </header>
    <article class="content__article">
      {{articleData pageText}}
    </article>
  `;
}
Enter fullscreen mode Exit fullscreen mode

Here is the result of the article page based on received data from the MediaWiki API:

Article page user-interface

Bookmark Page

I now carry onto now creating the final page of the application which is the bookmark page. For this page, a collapsible list will need to be implemented so that I can categorise authors into a grouped list that contains their respected quotes’.

Furthermore, since both the "models" and "quotes" pages will share similarities, I therefore can create a single page design that both can share.

TIP: If you see a pattern between multiple pages that are almost identical, or the same, then you can use one page design to share between them instead of creating a separate design for each.

function bookmarkTemplate() {
  return `
    <header class="content__head">
      <h1 class="head__header">Bookmarks</h1>
    </header>
    <div class="content__container--hero">
      <ul class="container__list--bookmarks">
        {{bookmarkMarkup bookmarks}}
      </ul>
    </div>
  `;
}
Enter fullscreen mode Exit fullscreen mode

Here is the result of creating the bookmark page:

Bookmark page user-interface for models

Bookmark page user-interface for quotes


Conclusion

So we’ve finally made it to completing the design of this whole application! We can now move onto the next part of the application where we implement the entire logic for it.

If you have found this useful, then please drop a comment and a heart so that this post can reach more people who struggle to create pure complex JavaScript applications by themselves.

Thank you for very much, and I hope to see you and everyone else in the next post!

Top comments (1)

Collapse
 
artydev profile image
artydev

Thank you