4

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.

1
  • resolve your cropper object in $modal.open, but it's not best solution, you should have some factory which will return cropper constructor, and inside CropModalInstanceCtrl you will initialize it. Commented Aug 12, 2014 at 12:03

3 Answers 3

2

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);
                            }
                        });

                    };

                }
            };
        });
Sign up to request clarification or add additional context in comments.

1 Comment

Wow! Many thanks, works like a charm! I have modified it a little: var html = "<img></img>"; var newElem = $(html); newElem.attr("src", attrs.src);
0

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);
      }
   });

}

3 Comments

Still doesn't work. This code executes before even the modal is shown, so it has no effect on the DOM.
I have in mind some "dirty" solution. But better is to create a directive (thats the best practice for DOM manipulation). What do you prefer?
Directives are elegant. So if you could show me how to do it, I would be grateful.
-1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.