Yvonne Aburrow
Yvonne Aburrow

Reputation: 2728

Getting multiple Angular modals to work with http response data

I am building an application to authenticate with Moodle and get Json data from a Moodle web service, and using AngularJs to display the data in the app. There are multiple functions on the Moodle webservice, so I need multiple controllers in the Angular app.

I am using Visual Studio and Cordova to write the app.

With a lot of help from a colleague and StackOverflow, I now have multiple Angular modals working in my single page mobile application. (There's another StackOverflow question about multiple modals, but it doesn't tell you how to work with http response data. To do this, you need to use Angular bootstrap.

(This is one of those "ask your question and answer it yourself" posts - but further suggestions are welcome.)

Upvotes: 0

Views: 1184

Answers (2)

Yvonne Aburrow
Yvonne Aburrow

Reputation: 2728

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.

Upvotes: 0

atn
atn

Reputation: 904

$uibModal.open can accept resolve parameters, and you can pass parameter like pageData, resolving it with data received from server. E.g.

$uibModal.open({
  templateUrl: ..,
  controller: 'modalCtrl',
  resolve: {
    pageData: function () {
      return $http.get(..).then(function (response) {
        return response.data;
      });
    }
  }
});
..
// then inject it in your modal controller
myapp.controller('modalCtrl', ['$scope', 'pageData', function ($scope, pageData) {
  $scope.pageData = pageData;
}])

Upvotes: 1

Related Questions