Monday, 5 December 2016

Getting multiple Angular modals to work with http response data

Your app will undoubtedly have more than one modal (pop-up div), and it can be hard to see how to get more than one of them working in Angular. Here's a step-by-step guide to how to do it.


Step 1. Put the required script tags in your HTML
<script src="scripts/angular.min.js"></script>
<script src="scripts/ui-bootstrap.js"></script>
<script src="scripts/ui-bootstrap-tpls.min.js"></script> 
angular.min.js is the main Angular library; ui-bootstrap.js is the Angular UI bootstrap library; ui-bootstrap-tpls.min.js is the Angular templating script to make the modal template display properly.
Step 2. Put the modal template in your HTML, inside your ng-app div
    <div role="main" id="main" class="ui-content scroll" ng-app="myApp">
    <!--MODAL WINDOW for item details -->
        <script type="text/ng-template" id="itemModalContent.html">
             <div class="modal-dialog">
                  <div class="modal-content">
                        <div class="modal-header">
                             <button type="button" class="cancel right button" data-dismiss="modal" aria-hidden="true" ng-click="cancel()">
                                  <i class="fa fa-close"></i>
                             </button>
                             <span class="item-name">{{item.name}}</span>
                         </div>
                         <div class="modal-body">
                              <p>{{item.description}}</p>
                         </div>
                         <div class="modal-footer">
                              <button type="button" class="button cancel btn-default" data-dismiss="modal" ng-click="cancel()">Cancel</button>
                              <button type="button" class="button ok btn-primary" ng-click="ok()">Sign me up</button>
                         </div>
                  </div>
           </div>
     </script>
</div>
Step 3. In your myApp.js, add the modal instance controller
myApp.controller('myItemsModalInstanceCtrl', function ($scope, $uibModalInstance, item) {
    $scope.item = item;
    $scope.cancel = function () {
        $uibModalInstance.close();
        $('.overlay').hide();
    };
});
Step 4. Call the modal instance controller from the item controller
myApp.controller('myItemsCtrl', function ($scope, $http, $uibModal) {
    url = concatUrl + 'local_servicename_ws_function_name';

    $http.get(url).then(function (response) {
        $scope.items = response.data;
        $scope.open = function (item) {
            $('.overlay').show();
            var modalInstance = $uibModal.open({
                controller: "myItemsModalInstanceCtrl",
                templateUrl: 'myItemModalContent.html',
                resolve: {
                    item: function () {
                        return item;
                    }
                }
            });
        };
    })
});
Step 5. Add a button to trigger the modal
This goes inside the ng-repeat block
<a data-toggle="modal" ng-click="open(item)">{{item.name}}</a> 
Additional notes
Put the modal template script inside the ng-app div, but outside the ng-repeat block.
This works with multiple modal calls inside a ng-repeat block, and with multiple ng-repeat blocks and modal templates in a page. You do need to make sure that the ng-repeat block repeats item in items, and that the modal template references item.
NB: code is supplied 'as is' without any commitment to it being fit for purpose and is also supplied without any commitment to maintenance or support.