Learn JavaScript by Building a Shopping App in CodePen

Learn by doing! The best way to learn JavaScript is with projects, so we’ll be building a shopping app in CodePen.

In this tutorial, we’ll learn how JavaScript can manipulate data and the DOM to create a multi-screen, dynamic web app, right inside CodePen. We will walk through the app-building process together: from creating app screens in HTML & CSS, to adding basic JavaScript functionality with button presses, to adding basic data processing. This tutorial is aimed at beginner developers.

Lesson Outline

The following is a tutorial that was presented at JS Conf Korea 2019 on September 3, 2019. It is a 4-part tutorial. The first part (Introduction & Overview) is presented here, but the other three parts are part of an online course I’m creating.

  1. Introduction <this part>
  2. Building the Shopping List Screen
  3. Building the Store Screen
  4. Building the Cart Screen

Material required

Introduction

As you may have noticed in my bio, my name is Aaron Snowberger, and I’m a frontend designer/developer who likes to dabble in backend and mobile technologies. My current passions include React, React Native, Node, and the WP REST API. I’m also a Google Certified Trainer who has taught computer science and graphic design in high school since 2013. I’m passionate about helping new learners discover the joys of JavaScript.

The web project this tutorial introduces is for a project that I built with my high school students in the Spring 2019 semester.

My class began the project with a review of HTML structure and CSS styles in order to create the overall look and feel of the web app. But the project’s main focus was to introduce my students to the beauty of JavaScript, and that is what the bulk of the tutorial will cover.

Why JavaScript

There are many reasons why JavaScript is a particularly useful programming language for new learners. Here are just a handful of them:

  1. JS is the third leg of the code-tripod that builds websites. Whereas HTML & CSS are not really programming languages per se (they are markup languages concerned with presentation, not function), JS is actually a functional programming language that can create interactive applications – and not just online brochures.
  2. JS is everywhere. The majority of the world’s websites utilize JavaScript somewhere – it provides much of the interactivity on a site – and it can also be used to build mobile applications (React Native, NativeScript). As such, the majority of the world’s population with access to the Internet is in contact with JavaScript on a daily basis.
  3. JS is noob-friendly and (relatively) easy to learn. Compared with many other true programming languages, JavaScript’s syntax and key concepts are rather straightforward and relatively easy to learn. So much so that middle school and high school students can pick it up, and there are even some block-building languages (like Blockly and Scratch) which are based on JavaScript and taught to even younger students. JavaScript is also one of the easier languages to debug.
  4. JS is also quite powerful. Some of the top websites in the world like Facebook, Instagram, AirBnB, and Netflix utilize JavaScript in their webpages and mobile apps. JavaScript can be used to power either the frontend or the backend of websites, and there are hundreds of very powerful frameworks and libraries of code available to work with.
  5. JS is undoubtedly fun to work with. By its very nature, powering websites and providing their functionality, JavaScript is highly interactive and visual, giving you the ability to build animations, powerful UIs, games, and apps. Plus, it’s even more fun when you realize you can build something that millions of people around the world can enjoy together.
  6. Learning JS can lead to a bright future. The JavaScript ecosystem is rapidly evolving and has seen much growth and change in recent years. As such, JavaScript skills are in high demand and salaries for skilled JavaScript developers are also high. Additionally, by learning the fundamental concepts all programming languages share (loops, conditionals, functions, classes, and so on), students can more easily pick up skills in additional – or more difficult languages as well.

About the Shopping App Project

AKA “How we’ll build this…”

JavaScript is primarily used to access and modify elements within a website. Therefore, we need to learn JavaScript by coding a project that has multiple moving parts, buttons, and interactive elements. A shopping app provides just such an opportunity.

Project Considerations

Each of the three “screens” in this app will be discussed in more detail below, but here is a quick overview of what we want each screen to do and how.

  1. Shopping List Screen
    • Performs like a To-Do List
    • We click a button to “add” or “remove” an items from the list
    • Type in the input field to “create” a new item (task)
    • Drag an item to the side to “delete” it (animate this)
    • Include Reset buttons to restore the original list to its defaults
    • Also include additional visual feedback (CSS animations) so the user can see what effect their interactions are having on the app
  2. Store Screen
    • This needs to include a collection of data – say at least 20 different items we can Search through and Add to our cart
    • We want to be able to change the View Type (from list to grid and vice versa – CSS Grid is a perfect tool for this)
    • We want to include filters such as Category, Price, and so on
    • We also want the Store to be searchable
    • We need to include some functionality to “Add” items to our cart so that when we click over to the Cart Screen, those items are there
    • We also need some kind of animation or visual feedback for the user (this can be handled with pop-up “Toast” notifications)
  3. Cart Screen
    • The cart will contain “cloned child nodes” from the Store Screen when the user clicked “Add to cart”
    • It needs to be able to dynamically update quantities and prices
    • And we also want to include some kind of nifty Checkout progression or modal and possibly a nice “shipped out” animation

First, some notes on HTML & CSS

  • HTML Structure
    • Use semantic markup (<nav> or <aside> rather than always <div>) & descriptive class names (like "shopping-list-item")
    • This helps you to think in a more modern, modular style when you build the structure (like components) first
  • CSS Style
    • Some useful visual indicators and design tools include:
      • My personal favorite design touch is using a dark bottom-border and light top-border on each list item – to give the appearance of three-dimensions and shadows
      • Transitions for everything are useful
      • Animations & keyframes also allow us to give visual clues to the user by doing things like jiggling the Cart icon when an item is added or removed
      • Additionally, transforms, opacity, and positioning can help us a lot
    • CSS Grid & Flexbox are also particularly useful tools (especially since React Native utilizes flexbox, so it’s good practice here if we want to work with React Native later)

1: Shopping List

Originally, this shopping app was designed to behave primarily like a To-Do list. So, it was more like a shopping list app that incorporated the following:

  1. A pre-built list of items
  2. To which new items can be added (input field)
  3. Items can be clicked on and marked as completed (purchased) with a strikethrough
  4. Or items can be removed from the list altogether (by dragging it off the screen)

After these initial functions were built, it seemed like a good idea to allow users to also do them in bulk, so the following buttons were added:

  1. Empty Cart – systematically goes through the list of items and removes the strikethrough, also returns the cart number to zero
  2. Delete List – systematically (and programmatically) removes each item from the list by “dragging” it off the screen in order
  3. Reset All – systematically resets the list to its original defaults by adding all the items back in

In addition to the functionality listed above, in order to provide adequate visual feedback to the user, CSS transitions, animations, and pseudo-elements were added to make the app appear as though every button click or input was having a (non-simultaneous) effect.

This meant that all the functionality of the app was given a 300-1200ms transition, for adding, deleting and so on. “Purchased” items appear to float up “into” the shopping cart, and bulk actions don’t happen all at once, but sequentially with a short delay between each item.

Shopping List Toolbox

The following is a list of necessary JavaScript knowledge to add to our mental toolbox in order to build the Shopping List screen:

Let’s build the Shopping List Screen!

Checkout the finished product in the CodePen below. Investigate the JS code in the editor to learn how it all works.

Completed Shopping List Screen.

2: Changing Screens

Technically, this is not another screen that we need to code, but rather the ability to seamlessly transition between screens. Therefore, it deserves its own subsection in which to discuss WHAT we want to do and HOW we want to do it.

  • Considerations:
    • Let’s make the screens appear to shift from left to right as we click between them. This means we need to make the width of our app <div> at least as wide as three screens, and then we want to absolutely position it where it needs to be for each visible screen.
    • Additionally, we need to change how the input field works:
      • On the Shopping List Screen, it adds items to our list
      • On the Store Screen, it should search the store
      • On the Cart Screen, it should search the cart
    • And of course, we want to add some Toast notifications (pop-ups) to indicate to the user what is going on

Changing Screens Toolbox

The following is a list of necessary JavaScript knowledge to add to our mental toolbox in order to build the Change Screens transitions and functionality:

  • JavaScript
  • CodePen
    • Additionally useful is being able to Add External CodePens into your next working model with CSS or JS code pre-built. This can help you to separate out different features and keep you CodePen code a little simpler.
    • For example, after building the Shopping List Screen in the previous section, I load its CSS and JS into every other CodePen I create (all the other Screens) to carry over its styles and functions.

Let’s build the Change Screens functionality!

Checkout the finished product in the CodePen below. Investigate the JS code in the editor to learn how it all works.

Completed Change Screens transitions.

3. Store

This is Screen #2 that we will build, the Store. You can see from the screenshot that this screen adds our collection of data (stored in a JavaScript array), a few interactive buttons on the store itself and on each item, and changes the input field to search for items in the store. Let’s run over our considerations for the Store Screen once again:

  • Considerations
    • Collection of data – say at least 20 different items (stored in a JS array)
    • Buttons to change the View Type (from list to grid and vice versa – the grid icon at the upper-right corner of the store is what we’ll use)
    • Filters: Relevance – Lowest Price – Highest Price
    • Search bar: although not instantaneous search, when ENTER is pressed, it returns (and displays) an array of the relevant items as well as a notification for the results it found (and an “x” button to clear the search) – see below
    • When “Add to Cart” is pressed, we need to clone the DOM node and add it to the array of items that are present in our Cart screen (so that when we click over there it will already be in the Cart)

Store Screen Toolbox

The following is a list of necessary JavaScript knowledge to add to our mental toolbox in order to build the Store screen:

Let’s build the Store Screen!

Checkout the finished product in the CodePen below. Investigate the JS code in the editor to learn how it all works.

Completed Store Screen.

4. Cart + Checkout

The third and final Screen we need to code for our app is the Cart Screen which will include a Checkout modal. Each item that we “Added to Cart” in the Store screen appears in our list here (as cloned DOM nodes).

Beneath the Cart list (not pictured) is a “Checkout (3)” button – with the quantity of items to purchase, and a “Total: $” field, both of which are dynamically updated as we add (or remove) items in the Cart.

Above the Cart list, is the Checkout modal progression: REVIEW – PAYMENT – COMPLETE. When we click the “Checkout (3)” button, this should take us through the full payment process to a “shipped out” animation at the end.

  • Considerations
    • Cloned child nodes are absolutely necessary to make the app function seamlessly between Store and Cart screens. This is because we are not actually loading different screens and passing data between them, but instead we continuously remain on the SAME page, and just push a different area into our iPhone screen based on the section of the app we want to load. Therefore, when we “Add to Cart” we actually need to create an identical copy of the DOM node that contains the item and add it to the Cart section.
    • Dynamic updates (in price or quantity) are controlled and managed with JavaScript’s MutationObserver that detects changes in the DOM and can respond accordingly, as well as custom HTML data attributes to retrieve the relevant information we need.
    • The Checkout Modal is a straightforward implementation that requires no special implementation methods.

Cart Screen Toolbox

The following is a list of necessary JavaScript knowledge to add to our mental toolbox in order to build the Cart screen:

  • JavaScript
    • Useful functions
      • .cloneNode() – to copy the DOM node containing our desired item
      • .appendChild() – to add the cloned node to the Cart
      • MutationObserver – to listen for changes in the DOM
        • This JavaScript feature in particular was the most important thing that I discovered while building the app. There is no other way to listen for changes in the DOM and respond to them without reloading the page.
      • parseFloat() – to deal with updating our prices
      • .toFixed(2) – also for updating prices (limit the decimal to 2 places)
      • .forEach() – to perform the same action on all DOM nodes in an array
  • HTML data attributes – we are using data-item-price

Let’s build the Cart Screen!

Checkout the finished product in the CodePen below. Investigate the JS code in the editor to learn how it all works.

Completed Shopping List Screen.

Just Keep Learning

I hope you found this tutorial session informative and interesting! And I encourage you to always “Just Keep Learning” and experimenting, building new projects, and trying things out. Below is a list of helpful resources you might find useful in your journey.

Resources

View the FULL CodePen Collection (including Start and End points for every screen) here:

Coding an Advent Calendar: Day 14

This year, I decided to create an Advent Calendar website in HTML5, CSS3, and JavaScript. My hopes for the site are to showcase some of my frontend development abilities as well as make something fun, functional, and reusable.

Day 14

Individual Post Styles
As I mentioned yesterday, I wanted to only show one WordPress post at a time when any package is clicked on. So, that’s what I set about doing today (as the Featured Image above shows). There are a few things I still need to take care of however:

  1. IF the Gift clicked on doe NOT (yet) have a Post for that date, show some kind of “Coming Soon” message.
  2. The Posts need to either be in a Carousel that mirrors the Gift carousel, OR they need to be dynamically loaded by the WP REST API and React based on the ID number (date) of the Gift clicked on.
  3. The “prev” and “next” buttons need some style corrections (like text-alignment and z-index to place them OVER the Post border) as well as functionality.
  4. Ideally, if a user clicks “prev” or “next”, the Post background (dark blue) would remain unchanged, and only the Posts would slide left or right (as a carousel).
Codepen Collection
I was still having trouble with my Gift carousel being off by a few pixels each time the carousel rotated, and then I tried to make the Gifts scale when hovered over:

Oops. What happened?

Well, I decided that since I started having THIS problem with scaling the Gifts AND I was already having trouble with getting the carousel to display and function properly, I probably had an error in my code somewhere that I was overlooking. Therefore, I decided to start breaking apart all the various pieces and components of this project to take a closer look at each of them individually.

It turns out the scale problem was happening because I didn’t have some kind of <div class="gift-wrapper"> surrounding my Gifts. So scale was scaling the CSS image from the center of itself (and thus pushing it out of the center of the page), rather than from the center of the wrapper which would allow it to remain centered in the page. Here’s what it looks like now with a <div class="gift-wrapper">:

In addition to the Gift Component, I also extracted out the Countdown Clock, and the individual Blog Post Component into separate Codepens and added them to a Collection:

  1. Gift Component
  2. Countdown Clock Component
  3. Post Component

From here, it allows me to continue working on the individual Components for the site even from my Windows computer. And once these pieces are perfected, I can then compile them all back together again as a “real” website.

React-ify All the Things!

So, since I’ve now separated out all the Components of the project, I decided it would be a great time to convert my existing HTML into true React Components. Now, the only HTML I have sitting in the Codepens above are:

<div id="react-component-name"></div>

All the markup is now handled entirely by React. And now, I feel like I’m ready to continue with Ray Villalobos’ Course: Building a Web Interface with React.js to learn better how I can get these various Component pieces to interact with each other better.

Side note: One additional thing I learned while working with these React Components is that: in order for jQuery (or any other JavaScript) to work and interact with these Components, React must be allowed to BUILD the Components on the page FIRST – before any other JavaScript functions are declared. Otherwise, jQuery will attempt to bind a "click" function (for example) on a tag that has not yet been created.


Work Completed (to date)

  • December 14, 2016
    • More individual styling of REST Posts
    • Break apart the project into Component pieces & create a Codepen Collection
    • Convert all the old HTML into real React Components
  • December 13, 2016
    • Add JS handlers for “Today”
    • Better styling of REST Posts
    • Begin Building a Web Interface with React.js (Lynda.com)
  • December 12, 2016
    • Storybook on Windows (FAIL)
    • Continue styling <Tag> Components
    • Begin responsive styles
  • December 11, 2016
    • Begin separating out CSS per Component
    • Attempt to load in static files & Sass
    • Begin coding a Tag for the Gifts
  • December 10, 2016
    • Finish Lynda.com videos
    • Get all React Components working in Storybook
    • Begin creating a Christmas Scene
  • December 9, 2016
    • Learn and use Create-React-App
    • Learn and use Storybook for developing React Components in isolation
    • Update npm and node and figure out my git process between Windows and Mac
  • December 8, 2016
    • Use React and Babel via CDN to get it working “locally”
    • Install React developer Tools for Chrome
    • Create very basic React.js pages to learn it
  • December 7, 2016
    • Pull post data with the WP REST API in WordPress core!!
    • Write structural code for the React Component to be rendered
    • Install and setup BabelJS to compile the React code
  • December 6, 2016
    • Add README.md
    • Add a GitHub Issue to hold usable images
    • Add LICENSE
  • December 5, 2016
    • Create a GitHub repository and full site files for easier management
    • Setup Grunt.js to compile my Sass into CSS
    • Begin blogging about the process
  • December 4, 2016
    • Countdown clock (JS Date class & jQuery Easing) with SVGs
    • Dynamic text output for Year based on the current date
    • CSS only slider (off by 5px each slide)
  • December 3, 2016
    • CSS bow & ribbon
    • Footer with FontAwesome presents
    • Hover, active, and “Christmas Day” styles for footer presents
  • December 2, 2016
    • React.js + Axios.js initial code structure
    • Color palette
    • CSS → Sass
  • December 1, 2016
    • Let it snow
    • Typography choices
    • CSS presents (first design)
    • Design notes menu