One place for hosting & domains

      Single Page Apps with AngularJS Routing and Templating

      Introduction

      Single-page apps are becoming increasingly popular. Sites that mimic the single-page app behavior are able to provide the feel of a phone/tablet application. Angular helps to create applications like this easily.

      We’re just going to make a simple site with a home, about, and contact page. Angular is built for much more advanced applications than this, but this tutorial will show many of the concepts needed for those larger projects.

      Goals

      • Single page application
      • No page refresh on page change
      • Different data on each page

      While this can be done with just Javascript and AJAX calls, Angular will make this process easier as our app starts growing.

      File Structure

              - script.js             <!-- stores all our angular code -->
              - index.html            <!-- main layout -->
              - pages                 <!-- the pages that will be injected into the main layout -->
              ----- home.html
              ----- about.html
              ----- contact.html
      

      This is the simple part. We’re using Bootstrap and Font Awesome. Open up your index.html file and we’ll add a simple layout with a navigation bar.

      index.html

              <!DOCTYPE html>
              <html>
              <head>
                
                <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
                <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
      
                
                <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
                <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
                <script src="script.js"></script>
              </head>
              <body>
      
                  
                  <header>
                      <nav class="navbar navbar-default">
                      <div class="container">
                          <div class="navbar-header">
                              <a class="navbar-brand" href="/">Angular Routing Example</a>
                          </div>
      
                          <ul class="nav navbar-nav navbar-right">
                              <li><a href="#"><i class="fa fa-home"></i> Home</a></li>
                              <li><a href="#about"><i class="fa fa-shield"></i> About</a></li>
                              <li><a href="#contact"><i class="fa fa-comment"></i> Contact</a></li>
                          </ul>
                      </div>
                      </nav>
                  </header>
      
                  
                  <div id="main">
      
                      
                      
      
                  </div>
      
              </body>
              </html>
      

      For linking to pages, we’ll use the #. We don’t want the browser to think we are actually traveling to about.html or contact.html.

      Module and Controller

      We’re going to set up our application. Let’s create the angular module and controller. Check out the docs for more information on each.

      First, we have to create our module and controller in javascript. We will do that now in script.js.

      script.js

              
              var scotchApp = angular.module('scotchApp', []);
      
              
              scotchApp.controller('mainController', function($scope) {
      
                  
                  $scope.message = 'Main Controller message';
              });
      

      Let’s add the module and controller to our HTML so that Angular knows how to bootstrap our application. To test that everything is working, we will also show the $scope.message variable that we created.

      index.html

              <!DOCTYPE html>
      
              <!-- define angular app -->
              <html ng-app="scotchApp">
              <head>
                <!-- load bootstrap and fontawesome via CDN -->
                <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
                <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
      
                <!-- load angular via CDN -->
                <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
                <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
                <script src="script.js"></script>
              </head>
      
              <!-- define angular controller -->
              <body ng-controller="mainController">
      
              ...
      
              <!-- MAIN CONTENT AND INJECTED VIEWS -->
              <div id="main">
                  {{ message }}
      
                  <!-- angular templating -->
                  <!-- this is where content will be injected -->
              </div>
      

      Inside of our main div, we will now see the message that we created. Since we have our module and controller set up and we know that Angular is working properly, we will start working on using this layout to show the different pages.

      Injecting Pages into the Main Layout

      ng-view is an Angular directive that will include the template of the current route (/home, /about, or /contact) in the main layout file. In plain words, it takes the file we want based on the route and injects it into our main layout (index.html).

      We will add the ng-view code to our site in the div#main to tell Angular where to place our rendered pages.

      index.html

              ...
      
              
              <div id="main">
      
                  
                  
                  <div ng-view></div>
      
              </div>
      
              ...
      

      Since we are making a single-page application and we don’t want any page refreshes, we’ll use Angular’s routing capabilities.

      Let’s look at our Angular file and add it to our application. We will be using $routeProvider in Angular to handle our routing. This way, Angular will handle all of the magic required to go get a new file and inject it into our layout.

      AngularJS 1.2 and Routing The ngRoute module is no longer included in Angular after version 1.1.6. You will need to call the module and add it to the head of your document to use it. This tutorial has been updated for AngularJS 1.2

      script.js

              
              
              var scotchApp = angular.module('scotchApp', ['ngRoute']);
      
              
              scotchApp.config(function($routeProvider) {
                  $routeProvider
      
                      
                      .when('/', {
                          templateUrl : 'pages/home.html',
                          controller  : 'mainController'
                      })
      
                      
                      .when('/about', {
                          templateUrl : 'pages/about.html',
                          controller  : 'aboutController'
                      })
      
                      
                      .when('/contact', {
                          templateUrl : 'pages/contact.html',
                          controller  : 'contactController'
                      });
              });
      
              
              scotchApp.controller('mainController', function($scope) {
                  
                  $scope.message = 'Main Controller message.';
              });
      
              scotchApp.controller('aboutController', function($scope) {
                  $scope.message = 'About Controller message.';
              });
      
              scotchApp.controller('contactController', function($scope) {
                  $scope.message = 'Contact Controller message.';
              });
      

      Now we have defined our routes with $routeProvider. As you can see by the configuration, you can specify the route, the template file to use, and even a controller. This way, each part of our application will use its own view and Angular controller.

      Clean URLs: By default, Angular will throw a hash (#) into the URL. To get rid of this, we will need to use $locationProvider to enable the HTML History API. This will remove the hash and make pretty URLs. For more information: Pretty URLs in AngularJS: Removing the #.

      Our home page will pull the home.html file. About and contact will pull their respective files. Now if we view our app, and click through the navigation, our content will change just how we wanted.

      To finish off this tutorial, we just need to define the pages that will be injected. We will also have them each display a message from its respective controller.

      home.html

              <div class="jumbotron text-center">
                  <h1>Home Page</h1>
      
                  <p>{{ message }}</p>
              </div>
      

      about.html

              <div class="jumbotron text-center">
                  <h1>About Page</h1>
      
                  <p>{{ message }}</p>
              </div>
      

      contact.html

              <div class="jumbotron text-center">
                  <h1>Contact Page</h1>
      
                  <p>{{ message }}</p>
              </div>
      

      Working Locally: Angular routing will only work if you have an environment set for it. Make sure you are using http://localhost or some sort of environment. Otherwise Angular will spit out a Cross origin requests are only supported for HTTP.

      Once you have all the routing done, you can start to get really fancy with your site and add in animations. To do this, you will need the ngAnimate module provided by Angular. After that, you can animate your pages into view with CSS animations.

      For a tutorial on how to get animations on your site, read: Animating AngularJS Apps: ngView.

      Ideally, this technique would be used for an application after a person has signed in. You wouldn’t really want those pages indexed since they are personalized to that specific user. For example, you wouldn’t want your Reader account, Facebook logged in pages, or Blog CMS pages indexed.

      If you did want SEO for your application though, how does SEO work for applications/sites that get their pages built with Javascript? Search engines have a difficult time processing these applications because the content is built dynamically by the browser and not visible to crawlers.

      Making Your App SEO Friendly

      Techniques to make JavaScript single-page applications SEO friendly require regular maintenance. According to the official Google suggestions, you would create HTML snapshots. The basic overview of how it would work is that:

      1. A crawler would find a pretty URL (https://scotch.io/seofriendly#key=value)
      2. The crawler would then ask the server for the contents of this URL (in a special modified way)
      3. Web server returns content using an HTML snapshot
      4. HTML snapshot is processed by the crawler
      5. Search results then show the original URL

      For more information on this process, be sure to look at Google’s AJAX Crawling and their guide on creating HTML snapshots.

      SEO Article: We’ve written up a tutorial on how to make Angular SEO friendly. Give it a read if you’re interested: AngularJS SEO with Prerender.io.

      This was a very simple tutorial on how to get Angular routing to work with a layout and separate views. Now you can go ahead and create larger single-page applications. There is much more to learn with Angular and I’ll keep writing about different features along my learning journey of Angular.

      If anyone has any suggestions for future Angular articles or different ways to do what we’ve just done here (there are so many ways to write the same thing, it can drive a person insane), sound off in the comments.

      Further Reading

      If you are looking for more flexibility in routing like nested views and state-based templating instead of route-based, then you’ll definitely be interested in UI Router. For an article on UI Router: AngularJS Routing Using UI-Router

      Note: Added information on SEO for using this technique.

      Note: Updated article for AngularJS 1.2

      Build a Single Page Time Tracking App with Vue.js: Introduction

      Introduction

      Vue.js is simple. It is so simple that people often dismiss it as only suitable for small projects. While it is true the Vue.js core is just a view layer library, there are in fact a collection of tools that will enable you to build full-blown, large-scale SPAs (Single Page Applications) using Vue.js with a pleasant development experience.

      If you are already familiar with the basics of Vue.js but feel that the world of SPA is scary, this series is for you. We will first introduce the concepts, tools, and libraries needed in this first article, and then will walk you through the full process of building an example app in the rest of the series.

      Single-Page Applications (SPAs) are web apps that load a single HTML page and dynamically update that page as the user interacts with the app. SPAs use AJAX and HTML5 to create fluid and responsive Web apps, without constant page reloads.

      As stated in the above description taken from Wikipedia, the main advantage of SPAs is that the app can respond to user interactions without fully reloading the page, resulting in a much more fluid user experience.

      As a nice side effect, a SPA also encourages the backend to focus on exposing data endpoints, which makes the overall architecture more decoupled and potentially reusable for other types of clients.

      From the developer’s perspective, the main difference between SPAs and a traditional backend-rendered app is that we have to treat the client-side as an application with its own structure. Typically we will need to handle routing, data fetching and persistence, view rendering, and the necessary build setup to facilitate a modularized codebase.

      For a Vue.js-based SPA, here are the tools and libraries that we will use to fill in these gaps:

      • View Layer: Vue.js, of course 🙂
      • Routing: vue-router, the official router for Vue.js.
      • State Management: vuex, a state-management solution inspired by Flux/Redux, but designed specifically for Vue.
      • Server Communication: vue-resource, a plugin for interfacing with a RESTful backend.
      • Build Tool: Webpack and vue-loader for modules, hot-reloading, ES2015, pre-processors and most importantly, single-file Vue components.

      Let’s take a closer look at each part.

      The View Layer

      This series assumes you are already familiar with the basics of Vue.js. If you are not, you should be able to quickly pick it up by going through official guide and other tutorials available.

      The core concept when using Vue.js for large SPAs is dividing your application into many nested, self-contained components. We also want to carefully design how these components interact with one another by leveraging component props for the data flow and custom events for communication. By doing so, we dissect the complexity into small, decoupled units that are tremendously easier to maintain.

      Routing

      The official vue-router library handles client-side routing, and supports both hash mode and HTML5 history mode. It is a bit different from standalone routing libraries in that it deeply integrates with Vue.js and makes the assumption that we are mapping nested routes to nested Vue components.

      When using vue-router, we implement components that serve as “pages”, and within these components we can implement hook functions that are called when the route changes.

      State Management

      State management is a topic that only arises when your application’s complexity grows beyond a certain level. When you have multiple components that need to share and mutate application state, it can get very hard to reason about and maintain if you don’t have a layer in your application that is dedicated to managing such shared state.

      This is where Vuex comes in. You don’t necessarily need Vuex if your application is relatively simple – but if you are interested, here’s an excellent intro on what problem it solves by Anirudh Sanjeev.

      Server Communication

      We will be working with a RESTful backend in the example, so we are using the vue-resource plugin which is maintained by the PageKit team. Do note that Vue.js SPAs are backend-agnostic and can basically work with any data fetching solution you prefer, for example fetch, restful.js, Firebase or even Falcor.

      Build Tool

      This is probably the biggest hurdle that you’ll have to jump through if you are not familiar with the frontend build tool scene, and we will try to explain it here. Feel free to skip this section if you are already experienced with Webpack.

      First, the entire build toolchain relies on Node.js, and we will be managing all our library and tool dependencies using npm. Although npm started out as the package manager for Node.js backend modules, it is now widely used for front-end package management, too. Because all npm packages are authored using the CommonJS module format, we need special tooling to “bundle” these modules into files that are suitable for final deployment. Webpack is exactly such a tool, and you may have also heard of a similar tool called Browserify.

      We will be using Webpack for the series because it provides more advanced functionalities out of the box, such as hot-reloading, bundle-splitting, and static asset handling.

      Both Webpack and Browserify exposes APIs that allow us to load more than just CommonJS modules: for example, we can directly require() an HTML file by transforming it into a JavaScript string.

      By treating everything for your frontend including HTML, CSS, and even image files as module dependencies that can be arbitrarily transformed during the bundling process, Webpack actually covers most of the build tasks that you will encounter when building a SPA. We are primarily going to build the example using Webpack and plain NPM scripts, without the need for a task runner like Gulp or Grunt.

      We will also be using vue-loader which enables us to author Vue components in a single file:

      app.vue

      <template>
        <h1 class="red">{{msg}}</h1>
      </template>
      
      <script>
      export default {
        data () {
          return {
            msg: 'Hello world!'
          }
        }
      }
      </script>
      
      <style>
      .red {
        color: #f00;
      }
      </style>
      

      In addition, the combination of Webpack and vue-loader gives us:

      1. ES2015 by default. This allows us to use future JavaScript syntax today, which results in more expressive and concise code.

      2. Embedded pre-processors. You can use your pre-processors of choice inside single-file Vue components, for example using Jade for the template and SASS for the styles.

      3. CSS output inside Vue components are auto-prefixed. You can also use any PostCSS plugins you like.

      4. Scoped CSS. By adding a scoped attribute to the <style>, vue-loader will simulate scoped CSS by rewriting the template and style output so that the CSS for a specific component will not affect other parts of your app.

      5. Hot Reload. When editing a Vue component during development, the component will be “hot-swapped” into the running app, maintaining the app state without having the reload the page. This greatly improves the development experience.

      Now with all these fancy features, it could be a really daunting task to assemble the build stack yourself! Luckily, Vue provides vue-cli, a command-line interface that makes it trivially easy to get started:

      1. npm install -g vue-cli
      1. vue init webpack my-project

      Answer the prompts, and the CLI will scaffold a project with all the aforementioned features working out of the box. All you need to do next is:

      1. cd my-project
      2. npm install
      3. npm run dev

      For full details on what is included in the generated project, check out the project template documentation.

      We haven’t really written any real app code so far, but I hope we have got you excited about learning more.

      In the next article, Ryan Chenkie will start taking us through a series of building a full-fledged SPA using this stack. Stay tuned!

      CSS3 Page Landing Animations

      Introduction

      Today we’ll be looking at ways to spice up when people land on our sites. I just experimented with this a little bit on a personal project, CODE Hearted. You can see the logo and content are animated on page load so that it gives the page a little more life.

      Not only can we use this technique to add a little pizazz, but we can also use it for UI/UX purposes to guide the user’s eyes across our page. Let’s say we only want a tagline to show up that tells a user what our site is about, then 3 seconds later, the content shows up. The combinations for this are unlimited and definitely play around with these animations and let your imagination go crazy. I went a little overboard I think on some animations (we probably wouldn’t want everything on a page to move), but it was more for demonstration purposes.

      The main way to build this technique is using CSS3’s animation feature and the animation-delay.

      This demo won’t work in all browsers since it is purely CSS3.

      Let’s start by setting up our site. We are going to use the super awesome Animate.css by Dan Eden for our animations. Also Twitter Bootstrap. We can write up our own but we’ll use this to make it quick and easy.

      Folder/File Structure

      index.html

      We’ll set up the HTML needed to set up our page. We’ll load bootstrap and animate.css from a CDN.

      To use animate.css, we add a class of animated and the type of animation we want to use. These are found here on the cool demo page. After this, all the animations will run at the same time. We add specific classes to each to vary the animation time and that’s what gives us our varied effect.

      <!doctype html>
      <html>
          <head>
              
              <title>CSS3 Page Loading Animations</title>
          
              <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
              <link rel="stylesheet" href="http://cdn.jsdelivr.net/animatecss/2.1.0/animate.min.css">
              <link rel="stylesheet" href="css/style.css">
          
          </head>
          <body>
          <div class="container">
          
              <div id="header" class="row text-center">
                  <div id="logo">
                      <span id="danger">
                          <span class="dd animated bounceInDown">d</span>
                          <span class="da animated bounceInDown">a</span>
                          <span class="dn animated bounceInDown">n</span>
                          <span class="dg animated bounceInDown">g</span>
                          <span class="de animated bounceInDown">e</span>
                          <span class="dr animated bounceInDown">r</span>
                      </span>
                      <span id="zone">
                          <span class="zz animated bounceInDown">z</span>
                          <span class="zo animated bounceInDown">o</span>
                          <span class="zn animated bounceInDown">n</span>
                          <span class="ze animated bounceInDown">e</span>
                      </span>
                  </div>
          
                  <nav id="main-nav">
                      <ul class="list-unstyled list-inline">
                          <li><a id="demo-1" class="animated btn btn-danger" href="index.html">Demo 1</a></li>
                          <li><a id="demo-2" class="animated btn btn-danger" href="two.html">Demo 2</a></li>
                          <li><a id="demo-3" class="animated btn btn-danger" href="three.html">Demo 3</a></li>
                      </ul>
                  </nav>
              </div>
          
              <div id="main" class="row">
                  <div id="sidebar" class="col-sm-4">
                      <nav id="sidebar-nav">
                          <ul>
                              <li><a id="side-home" class="animated bounceInLeft" href="#">Home</a>
                              <li><a id="side-about" class="animated bounceInLeft" href="#">About</a>
                              <li><a id="side-work" class="animated bounceInLeft" href="#">Work</a>
                              <li><a id="side-contact" class="animated bounceInLeft" href="#">Contact</a>
                          </ul>
                      </nav>
                  </div>
          
                  <div id="content" class="animated bounceInUp col-sm-8 text-center">
                      <div class="row">
                          <div class="col-sm-4">
                              <img class="img-responsive animated bounceInUp" src="http://lorempixel.com/500/500/people">
                          </div>
                          <div class="col-sm-4">
                              <img class="img-responsive animated bounceInUp" src="http://lorempixel.com/500/500/nature">
                          </div>
                          <div class="col-sm-4">
                              <img class="img-responsive animated bounceInUp" src="http://lorempixel.com/500/500">
                          </div>
                      </div>
                  </div>
              </div>
          
          </div>
          </body>
      </html>
      

      Now we have a solid foundation for our site. Using animate, all of those things that are animated will now move when you view your site. Let’s add some more styling and then we’ll get to the animations.

          
          @import url(http://fonts.googleapis.com/css?family=Offside);
          
          html                            { overflow-y:scroll; }
          body                            { margin-top:40px; }
          
          
          #header                         { margin-bottom:50px; }
          
              
              #logo                       { color:#FFF; font-family:'Offside'; font-size:80px; margin-bottom:50px; margin-top:50px; }
              #logo span                  { display:inline-block; }
          
          
          #main-nav                       { margin-bottom:30px; }
          
          
          #sidebar                        {  }
          
          #sidebar-nav                    {  }
          #sidebar-nav ul                 { list-style:none; padding-left:0; }
          #sidebar-nav li                 {  }
          #sidebar-nav a                  { background:#428bca; color:#FFF; display:block; margin-bottom:10px; padding:20px; text-transform:uppercase;
              border-radius:2px; -moz-border-radius:2px; -webkit-border-radius:2px;
          }
              #sidebar-nav a:hover        { background:#3276b1; text-decoration:none; }
          
          
          #content                        { background:#FFF; min-height:400px; padding:20px;
              border-radius:2px; -moz-border-radius:2px; -webkit-border-radius:2px;
          }
          #content img                    { border-radius:2px; -moz-border-radius:2px; -webkit-border-radius:2px; }
          
          
          
              
              .dd                         { animation-delay:0.2s; -moz-animation-delay:0.2s; -webkit-animation-delay:0.2s; }
              .da                         { animation-delay:0.8s; -moz-animation-delay:0.8s; -webkit-animation-delay:0.8s; }
              .dn                         { animation-delay:0.6s; -moz-animation-delay:0.6s; -webkit-animation-delay:0.6s; }
              .dg                         { animation-delay:1s; -moz-animation-delay:1s; -webkit-animation-delay:1s; }
              .de                         { animation-delay:0.4s; -moz-animation-delay:0.4s; -webkit-animation-delay:0.4s; }
              .dr                         { animation-delay:1.2s; -moz-animation-delay:1.2s; -webkit-animation-delay:1.2s; }
          
              .zz                         { animation-delay:1.4s; -moz-animation-delay:1.4s; -webkit-animation-delay:1.4s; }
              .zo                         { animation-delay:0.4s; -moz-animation-delay:0.4s; -webkit-animation-delay:0.4s; }
              .zn                         { animation-delay:0.6s; -moz-animation-delay:0.6s; -webkit-animation-delay:0.6s; }
              .ze                         { animation-delay:0.5s; -moz-animation-delay:0.5s; -webkit-animation-delay:0.5s; }
          
              
              #side-home                  { animation-delay:0.2s; -moz-animation-delay:0.2s; -webkit-animation-delay:0.2s; }
              #side-about                 { animation-delay:0.6s; -moz-animation-delay:0.6s; -webkit-animation-delay:0.6s; }
              #side-work                  { animation-delay:0.8s; -moz-animation-delay:0.8s; -webkit-animation-delay:0.8s; }
              #side-contact               { animation-delay:0.3s; -moz-animation-delay:0.3s; -webkit-animation-delay:0.3s; }
          
              
              #content                    { animation-delay:1.5s; -moz-animation-delay:1.5s; -webkit-animation-delay:1.5s; }
                  #content img            { animation-delay:1.7s; -moz-animation-delay:1.7s; -webkit-animation-delay:1.7s; }
      

      And that’s it! By adding the variable animation-delays times you can create some pretty sweet animations.