Dealing with modal directives in angularjs

MOdal components are extremely common in web applications or even on small websites.

In the upcoming sections, we will show a simple modal solution loading content from a simple controller using the Bootstrap UI, and also an alternative way to extend it using a custom external template demonstrating the flexibility of custom directives with the Bootstrap UI.

Getting ready

As a starting point, we will use the generator-angm; the baseline code will be the default home directory.

At this point, we assume that you have the generator installed on your development environment and a project already started.

How to do it…

  1. Place the following highlighted code in the homeCtrl.js file in the home directory:
    /**
     * @ngdoc function
     * @name app.controller:HomeCtrl
     * @description
     * # HomeCtrl
     * Controller of the app
     */angular.module('bootstrap-ui-directives')
    // Passing the $modal to controller as dependency
    .controller('HomeCtrl', ['$scope', '$modal', function ($scope, $modal) {
      $scope.title = "Hello, Angm-Generator!";
    
      $scope.open = function () {
    
        var modalInstance = $modal.open({
          templateUrl: 'myModalContent.html',
          controller: 'ModalCtrl'
        });
    
      };
    
    }])

    • Now, let’s add the modal controller. For the example code, we use the same homeCtrl.js file to hold all the code examples. However, in production applications, you must, or at least should, have one controller for each goal. Let’s go to the second step and add the ModaCtrl function:
      // Passing $modalInstance to controller as dependency
      .controller('ModalCtrl', function ($scope, $modalInstance) {
      
        // Added some content to Modal using $scope
        $scope.content = "ModalCtrl, Yeah!"
      
        // Add cancel button
        $scope.cancel = function () {
          $modalInstance.dismiss('cancel');
        };
      })

       

      • Note that we have appended this controller to the homectrl.js file. Now, let’s add the modal HTML content to the home.html file inside the home directory. Add the following highlighted code:
        <div ng-controller="HomeCtrl">
          <div class="splash" style="width:600px; margin:0 auto; text-align:center">
              <h1>{{ title }}</h1>
              <p>This is a template for a simple home screen website. Use it as a starting point to create something more unique.</p>
              <code>app/home/home.html</code>
              <hr>
              <p><a ng-click="open()" class="btn btn-primary" role="button">Open Modal »</a></p>
          </div>
          <!-- Modal Script -->
          <script type="text/ng-template" id="myModalContent.html">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
              <h3 class="modal-title">Hello from Modal!</h3>
            </div>
            <div class="modal-body">
              Modal Content from: <b>{{ content }}</b>
            </div>
            <div class="modal-footer">
              <button class="btn btn-danger" ng-click="cancel()">Cancel</button>
            </div>
          </script>
        </div>

        • Note that we have added a custom template to display the modal called myModalContent.html. Open your Terminal window inside the application folder and type:
          grunt dev

          The result expected when the modal button is clicked is what we have in the following screenshot:

        • We can easily extend this functionality by creating a custom directive and an external template, as already mentioned earlier. To do this, perform the following steps and add the following code to your application:
          .controller('ModalCustomCtrl', function ($scope) {
            // Set show modal to false/ hide from HTML
            $scope.showModal = false;
          
            // Toggle function to show and hide modal from HTML
            $scope.toggleModal = function(){
              $scope.showModal = !$scope.showModal;
            };
          })
          // Modal Directive
          .directive('modal', function () {
            return {
              // Add a custom template for modal
              templateUrl: 'app/home/modal-tpl.html',
              restrict: 'E',
              transclude: true,
              replace:true,
              scope:true,
              link: function postLink(scope, element, attrs) {
                scope.title = attrs.title;
          
                scope.$watch(attrs.visible, function(value){
                  if(value == true)
                    $(element).modal('show');
                  else
                    $(element).modal('hide');
                });
          
                $(element).on('shown.bs.modal', function(){
                  scope.$apply(function(){
                    scope.$parent[attrs.visible] = true;
                  });
                });
          
                $(element).on('hidden.bs.modal', function(){
                  scope.$apply(function(){
                    scope.$parent[attrs.visible] = false;
                  });
                });
              }
            };
          })

           

          As we are extending a directive, we will use an external template called modal-tpl.html to demonstrate the flexibility of this directive. Let’s add the following HTML code:

          <div class="modal fade">
            <div class="modal-dialog">
              <div class="modal-content">
                <div class="modal-header">
                  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                  <h4 class="modal-title">{{ title }}</h4>
                </div>
                <div class="modal-body" ng-transclude></div>
                <div class="modal-footer">
                  <button class="btn btn-danger" data-dismiss="modal">Cancel</button>
                </div>
              </div>
            </div>
          </div>
          
          

          How it works…

          It is very simple to use the Angular UI Bootstrap components on Angular applications. Note that the generator we use already has Bootstrap installed and configured, though it is very simple to do this.

          Tip

          You can find more about the Angular Bootstrap UI on the official website at http://angular-ui.github.io/bootstrap/.

          In this example, we only use the Bootstrap built-in directive to enable a modal component. However, we don’t have direct contact with the directive’s code.

          In the second example, we extended this control and created our own directive called modal using a custom template:

          // Modal Directive
          .directive('modal', function () {
            return {
              // Add a custom template for modal
              templateUrl: 'app/home/modal-tpl.html',
              restrict: 'E',
              transclude: true,
              replace:true,
              scope:true,
              link: function postLink(scope, element, attrs) {
                scope.title = attrs.title;
          
                scope.$watch(attrs.visible, function(value){
                  if(value == true)
                    $(element).modal('show');
                  else
                    $(element).modal('hide');
                });
          
                $(element).on('shown.bs.modal', function(){
                  scope.$apply(function(){
                    scope.$parent[attrs.visible] = true;
                  });
                });
          
                $(element).on('hidden.bs.modal', function(){
                  scope.$apply(function(){
                    scope.$parent[attrs.visible] = false;
                  });
                });
              }
            };
          })

          To use it, we only need to declare it in our markup, within the given controller, as shown in the following example:

          <!-- Custom Modal -->
          <div ng-controller="ModalCustomCtrl">
            <div style="width:600px; margin:0 auto; text-align:center">
            <button ng-click="toggleModal()" class="btn btn-default">Open modal custom Directive</button>
            </div>
            <!-- Modal from Custom Directive-->
            <modal title="Modal Custom Directive" visible="showModal">
              Content Modal from: <b>Custom Directive</b>
            </modal>
          </div>

          With just a few lines of code, we have a very flexible custom modal directive.

          There’s more…

          The ui-bootstrap-tpls.js file has all the Bootstrap templates inline on the JavaScript file using the $templateCache function:

          angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
            $templateCache.put("template/modal/window.html", "<div tabindex=\"-1\" role=\"dialog\" class=\"modal fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" + " <div class=\"modal-dialog\" ng-class=\"{'modal-sm': size == 'sm', 'modal-lg': size == 'lg'}\"><div class=\"modal-content\" modal-transclude></div></div>\n" + "</div>");
          }]);

          Tip

          It is also possible to use dynamic content to fill the modal’s body content; we will see an example of this in the next topic.

           

           

Deven Rathore

Deven is an Entrepreneur, and Full-stack developer, Constantly learning and experiencing new things. He currently runs CodeSource.io and Dunebook.com.

Published by
Deven Rathore
Tags: angularjs

Recent Posts

Are There any Similarities Between Web Design and Art?

You may be surprised at how many of the same skills are involved!  Let’s get…

1 day ago

Tips on Increasing your organic traffic on WordPress

Introduction  As more and more people are using online services nowadays, most of the business…

2 days ago

Five Reasons You Should Start a Social Media Campaign

Small businesses need all the advertisements they can get. Traditional avenues for advertising, such as…

3 days ago

Top 10 SEO Writing Tips for Beginners 2021

Search Engine Optimization. It’s complicated, to say the least. Search engines, like Google, are constantly…

2 weeks ago

Should you become a freelancer in 2021? Pros and Cons

Freelancing and working from home was long considered idyllic by many, but the global pandemic…

2 weeks ago

The Leading Renewable Energy Trends in 2021

The past year saw slowdowns in the ongoing shift toward renewable energy in many countries…

2 weeks ago