Passing Data to (and from) a Modal Popup in Angular

Success! Perhaps naïve and a bit crude, but it is something that seems to work so far.

As part of playing with StrongLoop's Loopback framework, I am also beginning to learn about Angular via Loopback's examples. Today, I ran into needing to do something pretty basic in Angular, and it seems to be a bit harder to do than I expected... at least to someone very new to it.

The feature in question is the ability to pass parameters/info into a modal popup. The scenario is when you have a list of stuff, and you want to show a popup when the user clicks on one of the elements in the list, say for a confirm delete or something.

Anyone who has a list of stuff the user will interact with will need this feature, and so that's why it surprised me that it wasn't quite as straightforward as I anticipated.

Well, not straightforward to someone as new to Angular as myself.

So, below are the basics on one way that works - not a complete example, but this is kind of a "fresh note from the field", and may help someone nevertheless. It is based on Angular's sample on using the ui.bootstrap.modal functionality, and this stackoverflow post.

Here are the pieces:

  • Angular (of course)
  • Bootstrap
  • UI Bootstrap - Bootstrap components from the AngularUI Team
  • You have an html list where each row has some attributes unique for a row (id, etc.); here is a snippet in Jade syntax (N.B. The diminished clutter of writing and reading Jade for html is a pleasure, imo):
    
      tr(ng-repeat="file in files")
        td
          strong
          | {{file.originalFileName }}
        td
          button(ng-click="openConfirmDelete(file.originalFileName, file.id)",title="Delete")
          | Delete
    
    A basic list of stuff (Jade syntax)
    We want a styled popup specific to the row clicked

  • In your html file, define a script defining a template for the modal popup - here is a stripped-down one (yes, that's "raw" html inside the script tag):
    
      script#myModalContent(type='text/ng-template')
        .modal-header
          h3.modal-title Delete File {{name}}?
        .modal-footer
          button(ng-click="cancel()") Cancel
          button(ng-click="doDelete()") Yes, Delete File
    
    
    Defining the script "template" for the popup for Angular

  • In your controller js file, make sure and include 'ui.bootstrap", a la
    
       angular.module('app', ['angularFileUpload','ui.bootstrap'])
          .controller(...
    
    Referencing the UI Bootstrap stuff
    so it can be used

  • In the controller javascript (and I am assuming this is in definition of the controller that is used for the list), define the controller for the popup:
    
      var PopUpController = function($scope, $modalInstance, name,id) {
       
        $scope.name = name;
        $scope.doDelete = function() {  // this is the function called when the user 
                                        //  user clicks the "Yes Delete File" button              
          $modalInstance.close({doDelete:true, id:id}); //this gets passed back to 
                                                        // the code that created the popup
        };
        $scope.cancel = function () {
          $modalInstance.dismiss('cancel');
        };
      };
    
    Defining the controller for the modal confirmation popup

  • In the relevant controller for the list, define the function openConfirmDelete that will make use of both the script template and the PopUpController:
    
      ...).controller('FilesController', 
            function ($scope, $http, $modal) {
              $scope.openConfirmDelete = function (name,id) {
                 var modalInstance = $modal.open({
                                        templateUrl: 'myModalContent',
                                        controller: PopUpController,
                                        resolve: {
                                          name: function() {return name;}
                                          id: function () {return id;}
                                        }
                                     });
                                   });
    
                  modalInstance.result.then(function (opts) {
                      if (opts.doDelete === true) {
                            //you are now free to deal with the file/whatever,
                            //   as you will be able to get the id from opts.id
                            //  e.g, delete(opts.id);
                            // Note: as "id" is in a closure, I'm not sure it
                            //         is necessary to pass it back here, but
                            //         this shows how to pass anything back
                      }
                    }, 
                     function () {console.log('Modal dismissed at: ' + new Date());}
                  }); // modalInstance.result
              }; // openConfirmDelete
            ...
            ...
            }); //FilesController...
    
  • The final piece: creating the popup when
    the user clicks the "Delete" button on an item in the list

Whew.

No comments:

Post a Comment

Popular Posts