How to Creating Stateful Modals in AngularJS with Angular UI Router

View: 293    Dowload: 0   Comment: 0   Post by: hanhga  
Author: none   Category: Javascript   Fields: Other

9 point/2 review File has been tested

There are a number of ways to approach implementing modals in an AngularJS application, including the popular angular-dialog-service and the official Angular-UI Bootstrap modal

Introduction

There are a number of ways to approach implementing modals in an AngularJS application, including the popular angular-dialog-service and the official Angular-UI Bootstrap modal. In this article I’ll share how I like to handle modals in Angular, using another Angular-UI service, the ui-router.

Thinking in States

The core idea behind this approach is that modals are in fact unique states of your application. Consider an e-commerce site. When you click the “Add to cart” button, a modal pops up asking you to log in. You enter your details and click “Continue”, which show’s you another modal with the details of your cart.

You’ve just traversed a number of states that just happened to be in modals. If we think of modals as states, then it makes sense to use a state management tool to go to and from different modal states.

Getting Started with the UI Router

Let’s keep it simple to start with. First, we’ll install the ui-router and add it to our Angular app.

1. Create a Simple HTML Page

We’ll start by creating an index.html file with the following contents:

<!doctype html>
<html ng-app="modalApp">
  <head>
    <title>Modals with Angular and Ui-Router</title>
    <link rel="stylesheet" href="css/app.css" />
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/angular.min.js"></script>
    <script type="text/javascript" src="js/angular-ui-router.min.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
  </head>
  <body>
  </body>
</html>

jQuery has been included for some DOM work later on.

In addition to including the latest version of Angular itself, I’ve included the Angular UI Router, a CSS file (currently empty), and of course our app’s main JavaScript file. Let’s take a look at that next.

2. Create Your Angular App

The app.js file is incredibly simple at this point. We just create a module for our modalApp and then add the ui.router as a dependency:

angular.module("modalApp", ["ui.router"])

3. Fleshing Out the Interface

Before we can open a modal, we need a UI for the user to interact with. In this instance I’ve kept things simple with an “Add to cart button” in index.html:

<!doctype html>
<html ng-app="modalApp">
  <head>
    <title>Modals with Angular and Ui-Router</title>
    <link rel="stylesheet" href="css/app.css" />
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/angular.min.js"></script>
    <script type="text/javascript" src="js/angular-ui-router.min.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
  </head>
  <body>
    <h3>Pusheen Hoodie</h3>
    <p>Now you too can look like Pusheen!</p>
    <button>Add to cart</button>
  </body>
</html>

4. Configure the Initial States

We’re going to be defining a number of states for each of our modals, but there’s a bit of setup we need to do first. Since it’s likely that we’ll want to share behavior between our different modals, let’s create a parent Modal state that our individual modals can then inherit from. The following code belongs injs/app.js:

angular.module("modalApp", ["ui.router"]).config(function($stateProvider) {
  $stateProvider.state("Modal", {
    views:{
      "modal": {
        templateUrl: "modal.html"
      }
    },
    abstract: true
  });
});

We have defined a state called “Modal”. It’s an abstract state meaning it can’t be directly transitioned to. It only serves as a parent to it’s child states to offer shared functionality. We also defined a template for anamed view (also called modal). Naming your views is a good idea to avoid the wrong states loading into the wrong places in your app, especially if you’re using the ui-router for other states in your app.

5. Define the ui-view Directive for Our Modal to Load Into

The ui-router uses a directive called ui-view to determine where a state’s template should be loaded. We’ll include a ui-view directive on our index.html page:

<!doctype html>
<html ng-app="modalApp">
  <head>
    <title>Modals with Angular and Ui-Router</title>
    <link rel="stylesheet" href="css/app.css" />
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/angular.min.js"></script>
    <script type="text/javascript" src="js/angular-ui-router.min.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
  </head>
  <body>
    <h3>Pusheen Hoodie</h3>
    <p>Now you too can look like Pusheen!</p>
    <button>Add to cart</button>

    <div ui-view="modal" autoscroll="false"></div>
  </body>
</html>

Since we named our view “modal”, we need to pass this to the directive as well. Theautoscroll="false" setting prevents the ui-router from attempting to scroll the modal into view.

6. Creating Our First Actual Modal

Let’s go about defining our first actual modal. We’ll create a popup that asks the user if they’re sure they want to add the product to their cart.

angular.module("modalApp", ["ui.router"]).config(function($stateProvider) {
  $stateProvider.state("Modal", {
    views:{
      "modal": {
        templateUrl: "modal.html"
      }
    },
    abstract: true
  });

  $stateProvider.state("Modal.confirmAddToCart", {
    views:{
      "modal": {
        templateUrl: "modals/confirm.html"
      }
    }
  });
});

Simple as that. We defined a new confirmAddToCart state as a child of Modal using the router’s dot notation. We also specified a template for our new modal.

Since the confirmAddToCart modal is a child of the Modal state, the ui-router will look for a ui-viewdirective in the Modal state’s template (modal.html) in order to render the confirm template. Let’s create both of these templates next.

7. Create the Base Modal State’s Template

The Modal state’s template is responsible for creating a transparent backdrop to cover the app, as well as a holder of sorts, where we’ll load our different child state’s templates.

<div class="Modal-backdrop"></div>
<div class="Modal-holder" ui-view="modal" autoscroll="false"></div>

Here’s a few basic styles that belong in css/app.css:

*
{
  box-sizing: border-box;
}

.Modal-backdrop
{
 position: fixed;
 top: 0px;
 left: 0px;
 height:100%;
 width:100%;
 background: #000;
 z-index: 1;
 opacity: 0.5;
}

.Modal-holder
{
  position: fixed;
  top: 0px;
  left: 0px;
  height:100%;
  width:100%;
  background: transparent;
  z-index: 2;
  padding: 30px 15px;
}

8. Create the Confirm Modal’s Template

This template is for the actual modal box with the confirm message in it. The following code goes inmodals/confirm.html:

<div class="Modal-box">
  Are you sure you want to do that?
  <button>Yes</button>
</div>

Styling for the Modal-box:

.Modal-box
{
  margin: 0 auto;
  width: 100%;
  background: #fff;
  padding: 15px;
  border-radius: 4px;
  box-shadow: 1px 2px 5px rgba(0,0,0,0.3);
  position: relative;
}

@media screen and (min-width: 992px)
{
  .Modal-box
  {
    width: 50%;
    padding: 30px;
  }
}

9. Wire It All Up

Now that we have a parent modal state with a child state, and both of their templates, all that’s left to do is actually trigger the modal. The ui-router provides us with a directive called ui-sref which behaves similarly to the href attribute of an anchor tag. It will essentially link us to the state name we provide.

<!doctype html>
<html ng-app="modalApp">
  <head>
    <title>Modals with Angular and Ui-Router</title>
    <link rel="stylesheet" href="css/app.css" />
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/angular.min.js"></script>
    <script type="text/javascript" src="js/angular-ui-router.min.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
  </head>
  <body>
    <h3>Pusheen Hoodie</h3>
    <p>Now you too can look like Pusheen!</p>
    <button ui-sref="Modal.confirmAddToCart">Add to cart</button>

    <div ui-view="modal" autoscroll="false"></div>
  </body>
</html>

Now, when we click the button, the router will navigate us to the Modal.confirmAddToCart state. TheModal state’s template will load first into the ui-view directive in index.html. This will show our backdrop and prepare the holder. Then, the white confirmation dialog will load into the ui-view directive in the parent modal template and hey presto! We have a modal!

10. Closing the Modal

The first thing you might notice, is that you can’t close the modal. Let’s fix that.

AngularUI Router provides us with onEnter and onExit callbacks that fire off when entering and leaving states. We’ll use the onEnter callback to set up some event listeners that will close the modal. But that begs the question: How do we actually close it? Closing the state based modal is simply a matter of transitioning to a different state. Whether that be the state the modal originated from or just some default, no-op state is up to you. For now, let’s create an empty Default state and use that to navigate away from our modal state.

angular.module("modalApp", ["ui.router"]).config(function($stateProvider) {
  $stateProvider.state("Default", {});

  $stateProvider.state("Modal", {
    views:{
      "modal": {
        templateUrl: "modal.html"
      }
    },
    onEnter: ["$state", function($state) {
      $(document).on("keyup", function(e) {
        if(e.keyCode == 27) {
          $(document).off("keyup");
          $state.go("Default");
        }
      });

      $(document).on("click", ".Modal-backdrop, .Modal-holder", function() {
        $state.go("Default");
      });

      $(document).on("click", ".Modal-box, .Modal-box *", function(e) {
        e.stopPropagation();
      });
    }],
    abstract: true
  });

  $stateProvider.state("Modal.confirmAddToCart", {
    views: {
      "modal": {
        templateUrl: "modals/confirm.html"
      }
    }
  });
});

The events we set up are fairly trivial. We just need to listen for the esc key, as well as for any clicks on the backdrop. Furthermore an e.stopPropagation() call has been added to prevent clicks inside the modal bubbling up to the backdrop and closing the modal unintentionally.

Go ahead and test it out.

11. Transitioning to Another Modal

Now that we can open and close the modal, we can begin to see the true strength of this approach. Not only is it clean and meaningful to have each modal represented by a state, but it allows us to traverse states within those modals.

We started off asking users to confirm their purchase. Now, let’s show them a success message in another modal. Again, we’ll just define a new state and its associated template:

angular.module("modalApp", ["ui.router"]).config(function($stateProvider) {
  $stateProvider.state("Default", {});

  $stateProvider.state("Modal", {
    ...
  }

  $stateProvider.state("Modal.confirmAddToCart", {
    views:{
      "modal": {
        templateUrl: "modals/confirm.html"
      }
    }
  });

  $stateProvider.state("Modal.successfullyAdded", {
    views:{
      "modal": {
        templateUrl: "modals/success.html"
      }
    }
  });
});
<div class="Modal-box">
  Added! Yay, now you too can look like Pusheen :)
  <button ui-sref="Default">Awesome!</button>
</div>

Now, all that’s left to do is to link the “Yes” button from the confirm modal, to the new success state. While we’re there, we can add a “No” button that links to our default state to close the modal.

<div class="Modal-box">
  Are you sure you want to do that?
  <button ui-sref="Modal.successfullyAdded">Yes</button>
  <button ui-sref="Default">No</button>
</div>

And there you have it! State based, navigable modals. I find that treating modals as states is a sure fire way to ensuring your users have a smooth experience when using modals in your application.

How to Creating Stateful Modals in AngularJS with Angular UI Router

How to Creating Stateful Modals in AngularJS with Angular UI Router Posted on 17-03-2016  There are a number of ways to approach implementing modals in an AngularJS application, including the popular angular-dialog-service and the official Angular-UI Bootstrap modal 4.5/10 293

Comment:

To comment you must be logged in members.

Files with category

  • JUnit 5 State Of The Union using java

    View: 604    Download: 0   Comment: 0   Author: none  

    JUnit 5 State Of The Union using java

    Category: Javascript
    Fields: Other

    2.25/2 review
    JUnit 5 has been under development for about 14 months now and the prototype is almost a year old. Time to summarize what happened so far, where the project stands, and where it’s going.

  • Getting Started with Dropwizard using java

    View: 697    Download: 0   Comment: 0   Author: none  

    Getting Started with Dropwizard using java

    Category: Javascript
    Fields: Other

    2.25/2 review
    Dropwizard is a framework for building RESTful web services in Java. In this tutorial we’re going to have a look at how to get started with developing a Dropwizard application by building a new service from scratch.

  • Build Query NULL Value in MySql

    View: 319    Download: 0   Comment: 0   Author: none  

    Build Query NULL Value in MySql

    Category: Javascript
    Fields: Other

    2.5/2 review
    Misunderstanding NULL is common mistake beginners do while writing MySql query. While quering in MySql they compare column name with NULL. In MySql NULL is nothing or in simple word it isUnknown Value so if you use comparison operator for NULL values...

  • Manage Your JavaScript Application State with MobX

    View: 336    Download: 0   Comment: 0   Author: none  

    Manage Your JavaScript Application State with MobX

    Category: Javascript
    Fields: Other

    2.25/2 review
    This article was peer reviewed by Michel Weststrate and Aaron Boyer. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

  • Build Bringing Pages to Life with the Web Animations API

    View: 346    Download: 0   Comment: 0   Author: none  

    Build Bringing Pages to Life with the Web Animations API

    Category: Javascript
    Fields: Other

    4.5/2 review
    This article is by guest author Dudley Storey. SitePoint guest posts aim to bring you engaging content from prominent writers and speakers of the JavaScript community.

  • How to Style Google Custom Search Manually

    View: 325    Download: 0   Comment: 0   Author: none  

    How to Style Google Custom Search Manually

    Category: Javascript
    Fields: Other

    0/0 review
    Website owners very often decide on using Google’s Custom Search Engine (GCSE) for searching through their content instead of using built-in and/or custom search functionality. The reason is simple – it’s much less work, and most often it does the...

  • Test React Components Using Jest

    View: 5098    Download: 0   Comment: 0   Author: none  

    Test React Components Using Jest

    Category: Javascript
    Fields: Other

    4.5/1 review
    This article is by guest author Jack Franklin. SitePoint guest posts aim to bring you engaging content from prominent writers and speakers of the JavaScript community.

  • Programming Question Reverse String without using String function

    View: 783    Download: 0   Comment: 0   Author: none  

    Programming Question Reverse String without using String function

    Category: Javascript
    Fields: Other

    4.5/1 review
    Write a program to reverse string without using string function. You don’t have to use any in-built string library function. This problem can be solved by multiple approaches. Let’s check it.

 

File suggestion for you

File top downloads

logo codetitle
Codetitle.com - library source code to share, download the file to the community
Copyright © 2015. All rights reserved. codetitle.com Develope by Vinagon .Ltd