Bootstrap Modals with Angular

The not-so-simple approach — embedding a template into the html itself. This is probably not a recommended solution, but I was pressed for time. Anyway, the docs say you need: 1) a template and 2) a controller.  

Then…you need to listen to the controller

Then…you need to do something about the response

Ok, it’s not that easy, but I’m catching on!!


*** STEP 1 ***

For the HTML side of things (should be it’s own file):


<script type="text/ng-template" id="myModalContent.html">
 <div class="modal-header">
   <h3 class="modal-title" id="modal-title">Send this goal</h3>
 </div>
 <div class="modal-body" id="modal-body">
   <p>Email (s): <input class="form-control" type="text" ng-model="$ctrl.details.emailto" placeholder="Enter email(s) here" /></p>
   <p>Add comments for the beginning of your email here:</p>
   <textarea ng-model="$ctrl.details.emailnotes" class="form-control"></textarea>
 </div>

 <div class="modal-footer">
   <button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">Send</button>
   <button class="btn btn-warning" type="button" ng-click="$ctrl.cancel()">Cancel</button>
 </div>
</script>

*** STEP 2 ***

Somewhere on the html document, call the method that fires up the modal:


<button class="btn btn-warning" title="Email Goal" ng-click="emailGoal(goal)"><i class="glyphicon glyphicon-envelope"></i> Email</button>

*** STEP 3 ***

In the controller for the page, respond to the click event:


$scope.emailGoal = function (goal) {
  $ctrl.details.goal = goal;
  var modalInstance = $uibModal.open({
    animation: true,
    component: 'modalComponent',
    resolve: {
       details: function () {
          return $ctrl.details;
       }
    }
  });
  modalInstance.result.then(function (details) {
    $ctrl.details = details;
    // process the request to send email
    $scope.shareGoal( details );
  }, function () {
    // unless it gets dismissed, then do nothing!
    console.info('modal-component dismissed at: ' + new Date());
  });
};

*** STEP 4 ***

Of course, you have to have a modalComponent built in order for this to work. In my case, I have a separate file (cc-modals.js) for this purpose. Basically, it handles the bindings and passes the data back to the resolve “promise” above.


angular.module('ccModals').component('modalComponent', {
  templateUrl: 'myModalContent.html',
  bindings: {
    resolve: '<',
    close: '&',
    dismiss: '&'
  },
  controller: function () {
    'use strict';
    var $ctrl = this;
    $ctrl.$onInit = function() {
      $ctrl.details = $ctrl.resolve.details;
    };
    $ctrl.ok = function () {
      // console.log('send details: ' + JSON.stringify($ctrl.details));
      $ctrl.close({$value: $ctrl.details});
    };
    $ctrl.cancel = function () {
      $ctrl.details.emailto='';
      $ctrl.details.emailnotes='';
      $ctrl.dismiss({$value: 'cancel'});
    };
  }
});

*** STEP 5 ***

This is called in STEP 3 modalInstance.result.then

with the details. Basically, we just process the request now that the modal is closed


$scope.shareGoal = function( details ){
  console.log('shareGoal called '); // + JSON.stringify( details ) );
  GoalsService.SendGoal( details, function(results){
    if ( results.success ) {
      console.log('dashboard controller: Successfully sent email');
      $scope.buttonMessage = '<span class="alert alert-success">Successfully emailed this goal.</span>';
    } else {
      console.error('dashboard controller: unable to send email');
      $scope.buttonMessage = '<span class="alert alert-warning">Unable to send this goal. Please check your email and try again.</span>';
    }
  });
  $timeout(function () { $scope.buttonMessage = ''; }, 3000);
};

Simple, right?

Latest post: Blog Continues at daverphillips.com

Post an Insight

This site uses Akismet to reduce spam. Learn how your comment data is processed.