Search code examples
angularjsng-img-crop

How to pass data to the controller using angular ui modal?


When user choose the image file, I am try to open modal window to crop the image, but I cant pass it to the modal window controller and vice-versa. This is my code:

<!doctype html>
<html ng-app="ui.bootstrap.demo">
  <head>
    <script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>

    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.0.0.js"></script>
    <script src="example.js"></script>

<link href="ng-img-crop.css" rel="stylesheet" type="text/css">
<script src="ng-img-crop.js"></script>

    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>

<div ng-controller="ModalDemoCtrl">
                        <input id="coolButton" name="avatar" type="file" accept="image/*" class="form-control" placeholder="">

    <div class="hidden">
    <div id="myModalContent">
              <div class="modal-header">
            <h3 class="modal-title">I'm a modal!</h3>
        </div>
        <div class="modal-body">

            <div class="cropArea">
              <style>
                .cropArea {
                  background: #E4E4E4;
                  overflow: hidden;
                  width:300px;
                  height:350px;
                }
              </style>
              <img-crop image="myImage" result-image="myCroppedImage"></img-crop>
            </div>
            <div>Cropped Image:</div>
            <div><img ng-src="{{myCroppedImage}}"/></div>

            <ul>
                <li ng-repeat="item in items">
                    <a href="#" ng-click="$event.preventDefault(); selected.item = item">{{ item }}</a>
                </li>
            </ul>
            Selected: <b>{{ selected.item }}</b>
        </div>
        <div class="modal-footer">

            <button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
            <button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
        </div>
    </div>
    </div>
    <button type="button" class="btn btn-default" ng-click="open()">Open me!</button>
    <!--button type="button" class="btn btn-default" ng-click="open('lg')">Large modal</button>
    <button type="button" class="btn btn-default" ng-click="open('sm')">Small modal</button>
    <button type="button" class="btn btn-default" ng-click="toggleAnimation()">Toggle Animation ({{ animationsEnabled }})</button-->
    <div ng-show="selected">Selection from a modal: {{ selected }}</div>

</div>
  </body>
</html>

Here is the demo.


Solution

  • Just pass the $scope to the scope field when open the modal. this will let the modal use $scope as its parent scope. If the scope is not set, it will use $rootScope as its parent by default.

    var modalInstance = $uibModal.open({
          animation: $scope.animationsEnabled,
          //templateUrl: 'myModalContent.html',
            template: template,
          controller: 'ModalInstanceCtrl',
          size: size,
          scope:$scope, // set the scope 
          resolve: {
            items: function () {
              return $scope.items;
            }
          }
        });
    

    Or if u do want to make ur modal more independently. u need to pass the image's value in resolve just as u did to items.

    var modalInstance = $uibModal.open({
          animation: $scope.animationsEnabled,
          //templateUrl: 'myModalContent.html',
            template: template,
          controller: 'ModalInstanceCtrl',
          size: size,
          resolve: {
            items: function () {
              return $scope.items;
            },
            myImage:function(){
              return $scope.myImage
            } // send the image data to the modal's controller
          }
        }); 
    

    But in this way u must call '$scope.open' after the image was readed.

     reader.onload = function (evt) {
              $scope.$apply(function($scope){
                  $scope.myImage=evt.target.result;
                  $scope.open();
              });
          };
    

    UPDATE:

    $scope.myCroppedImage = null; // looks like u need to init it first
      $scope.ok = function () {
        $uibModalInstance.close({selectedItem:$scope.selected.item,myCroppedImage:$scope.myCroppedImage});
      };