Fork me on GitHub

Popeye

A simple modal library for AngularJS applications

Most modal libraries for Angular are either frustratingly complicated or annoyingly dependent on a ton of external stuff. Popeye is simple, self-contained, and just "pops up" when you need it to.

Isn't that all you really want, anyways?

Click me!

Step 1: Install

Popeye only depends on Angular - no jQuery, Bootstrap, or other libraries required: npm install angular-popeye or bower install angular-popeye

Step 2: Include

In your HTML: <script src="path/to/angular-popeye/release/popeye.js"></script>

<!-- optional, if you want some default styles and animation -->
<link rel="stylesheet" href="path/to/angular-popeye/release/popeye.css" />


In your Angular module dependencies: var mod = angular.module("MyApp", ["pathgather.popeye"]);


If you want to use the default animations, you'll also need to include ngAnimate, too.

Step 3: Popeye!

Inject the Popeye service to open a modal and pass along your options: var modal = Popeye.openModal(...);
The modal object returned is open and flexible. It has resolved, opened, and closed promises you can use to listen to the modal state, and exposes the scope and controller so you can interact with them:

mod.controller("myCtrl", function($scope, Popeye) {

  $scope.openUserProfile = function(userId) {

    // Open a modal to show the selected user profile
    var modal = Popeye.openModal({
      templateUrl: "my_modal_template.html",
      controller: "myModalCtrl as ctrl",
      resolve: {
        user: function($http) {
          return $http.get("/users/" + userId);
        }
      }
    });

    // Show a spinner while modal is resolving dependencies
    $scope.showLoading = true;
    modal.resolved.then(function() {
      $scope.showLoading = false;
    });

    // Update user after modal is closed
    modal.closed.then(function() {
      $scope.updateUser();
    });
  };

});
      

Step 4: Customize

Popeye ships with default CSS that will size your modals, add a blue background, vertically & horizontally center the modal, and add enter & leave animations. It's easy to customize all of this by adding your own containerClass and modalClass classes and then overriding the default rules. Here are a couple of examples:
Zoom! Small Boring.

(Check the demo source code to see how these are done.)

Step 5: Documentation

Popeye.openModal(options)

Creates a new PopeyeModal with the given options and opens it. This will cause any existing modals to close first before the new modal is resolved and then opened.

Returns the new PopeyeModal instance, which you'll usually want to hold on to.

By default, Popeye uses a containerTemplate that looks like this:

<div class="popeye-modal-container">
  <div class="popeye-modal">
    <a class="popeye-close-modal" href ng-click="$close()"></a>
    <-- your modal template is appended here -->
  </div>
</div>

The default styles in popeye.css absolutely position the container to cover the entire window, centers the modal within that container, and positions the close link in the top right. You can, of course, override all of this with your own CSS, or change the containerTemplate to your own template if you prefer.

There are lots of options for opening a modal. If you've used ngRoute routes or ui-router states, you should find these options familiar:

Option Details
template
(string)
HTML template that will be compiled with the modal scope & controller, then inserted into the modal container
templateUrl
(string)
URL to GET the HTML template that will be compiled with the modal scope & controller, then inserted into the modal container. This is overriden by template
bodyClass
(string)
Class to add to the body when a modal is open. By default, this is .popeye-modal-open
containerClass
(string)
Class to add to the modal container element
modalClass
(string)
Class to add to the modal element (which contains your template)
scope
(object)
$scope to use for the modal template. By default, a new scope is created off of $rootScope. For convenience, a $close() function is added to the scope that can be used to close the modal
controller
(string or function)
$scope to use for the modal template. By default, a new scope is created off of $rootScope
resolve
(object)
A map of dependencies which are injected into the controller. If any of them are promises, wait until all are resolved before instantiating the controller. Each value should be a function that returns the dependency (see the ngRoute or ui-router docs for lots of examples of this pattern)
locals
(object)
A map of dependencies which are injected into the controller. This is similar to resolve but each value is the dependency itself. This is more to just pass in values that are directly injected to the controller. By default, a modal local is injected to the controller for easy access to the modal instance itself
containerTemplate
(string)
HTML template that acts as a container for the modal template. The compiled template is appended to this container.

NOTE: if you override this option, you must include a .popeye-modal element so that Popeye knows where to insert your modal template
containerTemplateUrl
(string)
URL to GET the HTML template that will provide a container for the modal template. This is overriden by containerTemplate, which has a default value, so you'll need to set that to null in order to use this option
keyboard
(boolean)
Whether or not the ESC key should close the current modal. Default is true.
click
(boolean)
Whether or not clicking on the modal container element should close the current modal. Default is true.

Popeye.closeCurrentModal(value)

Calls close(value) on the currently active PopeyeModal if there is one.

Returns the current PopeyeModal instance (which is now closing)

Popeye.isModalOpen()

Returns whether or not a modal is currently open.

PopeyeModal

This object handles resolving, opening, and closing modals. A new instance is created on each call to Popeye.openModal. You can use this object to wait on the various promises to do something when the modal is resolved, opened, or closed. Each instance also exposes pretty much all of it's internals which you can use to add whatever logic you need.

Properties include:

Property Details
close(value)
(function)
Closes the modal and then resolves the closed promise with the given value
open
(function)
Opens the modal, after resolving any resolve dependencies first. You typically won't call this directly
resolve
(function)
Resolves the modal's resolve dependencies. You typically won't call this directly
closed
(object)
Promise that is resolved once the modal is removed from the DOM (note this does not resolve until after any $animate animations are finished). The promise will resolve to the value provided to close(value), if given
opened
(object)
Promise that is resolved once the modal is compiled and added to the DOM (note this does not resolve until after any $animate animations are finished)
resolved
(object)
Promise that is resolved once all the modal's resolve dependencies are resolved
options
(object)
The options that were used for this instance
element
(object)
The jQuery/jqLite element of the compiled modal template
container
(object)
The jQuery/jqLite element of the compiled modal container template

PopeyeProvider

The Angular provider for the Popeye service. You can use this provider to configure default options for your application by modifying the defaults property like this:

var myApp = angular.module("myApp", ["pathgather.popeye"]);
myApp.config(function(PopeyeProvider) {
  PopeyeProvider.defaults.containerClass = "my-modal-window";
});