itachi
itachi

Reputation: 3597

AngularJS: Modify Bootstrap Modal after loading content

I want to use this pretty image cropper in my AngularJS project. When I use it the "normal" way, that is on a plain page, everything works fine. The problem is that I want to put it on to the Bootstrap modal dialog.

In order to initialize the cropper, I am supposed to execute this snippet:

$(".cropper").cropper({
    aspectRatio : 1.618,
    done : function(data) {
        console.log(data);
    }
});

But it has to be executed after the DOM of the modal is loaded. So I have tried to run it like this:

$scope.onCropOpen = function() {
    var modalInstance = $modal.open({
        templateUrl : 'cropModal.html',
        controller : CropModalInstanceCtrl
    });

    modalInstance.opened.then(function() {
        $(".cropper").cropper({
            aspectRatio : 1.618,
            done : function(data) {
                console.log(data);
            }
        });
    });
};

Unfortunately, the cropper still is not being initialized. I know that it should work after calling it when the modal is loaded, because I ran it manually from the browser console (with the modal dialog open) and then the cropper "magically" initialized.

Upvotes: 4

Views: 2153

Answers (3)

itachi
itachi

Reputation: 3597

Vitali's solution is done the proper way and definitely should be used. But if someone still needs a brute method, this worked for me as well:

modalInstance.opened.then(function() {
    $timeout(function() {
        $(".cropper").cropper({
            aspectRatio : 1.0,
            done : function(data) {
                console.log(data);
            }
        });
    });
});

Generally, this type of solutions should be avoided because timeouts might be treacherous.

Upvotes: -1

Vitali Kaspler
Vitali Kaspler

Reputation: 1410

Here is a very simple directive that can show you the direction. Instead of defining element with class ".cropper", create element "image-cropper" (since directive name is "imageCropper"):

<image-cropper></image-cropper>

This is a pretty general snippet that should work in similar way for any jquery plugin.

*Don't forget to change module name from "myApp", to the name of your application module...

angular.module("myApp").directive('imageCropper', function ($parse) {
            return {
                restrict: "E",
                replace: true,

                compile: function (element, attrs) {
                    var modelAccessor = $parse(attrs.ngModel);

                    var html = "<img></img>"; 
                    var newElem = $(html); 
                    newElem.attr("src", attrs.src);
                    element.replaceWith(newElem);

                    return function (scope, element, attrs, controller) {

                        element.cropper({
                            aspectRatio : 1.618,
                            done : function(data) {
                                console.log(data);
                            }
                        });

                    };

                }
            };
        });

Upvotes: 2

Vitali Kaspler
Vitali Kaspler

Reputation: 1410

Try to put the jquery code inside CropModalInstanceCtrl function:

var CropModalInstanceCtrl = function ($scope, $modalInstance) {

   $(".cropper").cropper({
      aspectRatio : 1.618,
      done : function(data) {
         console.log(data);
      }
   });

}

Upvotes: 0

Related Questions