James N James N - 1 year ago 453
AngularJS Question

angular material modal and ng-file-upload

I am working on image upload using angular material, ng-file-upload, and ng-imgcrop-extended. I was previously using all of this on a normal page, and everything was working fine, but requirements have changed and I had to move this logic to a modal.

The way it works is I am using

to crop the photos, and
does the uploading. So right now, I have an element listening to the file select, and that handles the cropping. Right now however, it is not listening to the file select, and I can only reason that is from the modal.

Here is my code

modal render

$scope.headshotModal = function(ev) {
var useFullScreen;
useFullScreen = ($mdMedia('sm') || $mdMedia('xs')) && $scope.customFullscreen;
locals: {
p: $scope.persona
controller: 'ImagesController',
templateUrl: 'application/views/images/image_modal.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: useFullScreen
}).then((function(answer) {
$scope.status = 'You said the information was "' + answer + '".';
}), function() {
$scope.status = 'You cancelled the dialog.';
$scope.$watch((function() {
return $mdMedia('xs') || $mdMedia('sm');
}), function(wantsFullScreen) {
$scope.customFullscreen = wantsFullScreen === true;


angular.module('App').controller('ImagesController', [
'$scope', 'p', '$mdDialog', 'ImageService', '$routeParams', function($scope, p, $mdDialog, ImageService, $routeParams) {
var handleFileSelect;
$scope.persona = p;
$scope.uploadedImg = false;
$scope.myCroppedImage = '';
$scope.myImage = '';
$scope.blockingObject = {
block: true
$scope.callTestFuntion = function() {
$scope.blockingObject.render(function(dataURL) {
$scope.showRender = true;
console.log('via render');
$scope.blockingObject.callback = function(dataURL) {
console.log('via function');
handleFileSelect = function(evt) {
var file, reader;
file = evt.currentTarget.files[0];
$scope.uploadedImg = true;
reader = new FileReader;
reader.onload = function(evt) {
$scope.$apply(function($scope) {
$scope.myImage = evt.target.result;
angular.element(document.querySelector('#imgInput')).on('change', function() {
// this function runs the code needed. it is not being triggered
$scope.thenRedirect = function() {
return window.location.href = "personas/" + $scope.persona.slug;
$scope.testCrop = function(file) {
ImageService.uploadCroppedImg(file, 'headshot', $routeParams, $scope.cropAttributes);
return $scope.thenRedirect();
$scope.cancel = function() {
$scope.uploadedImg = false;
return $scope.showRender = false;
$scope.hide = function() {
return $scope.cancelOut = function() {


md-dialog.fs [style="width: 100%; margin-left:25%; margin-right: 25%;" aria-label=("Image Edit") ng-cloak=""]
h2 Image Edit
span flex=""
md-button.md-icon-button [ng-click="cancelOut()" aria-label="Cancel"]
h2.text-center Edit Your Headshot

| Select an image file:
input#imgInput [type="file" ngf-select accept="image/*" ng-model="headshotFile"] /
/ [ng-show='uploadedImg']
md-button.render-btn[ng-click="callTestFuntion()"] Render
img-crop cropject='cropAttributes' area-type="rectangle" image="myImage" live-view="blockingObject" result-image="myCroppedImage"

a.img-upload [href="#" ngf-select="uploadBanner($file)" ngf-dimensions="$width > 149 && $height > 149"]
span Banner

a.img-upload[style='cursor: pointer;'ng-click="testCrop(headshotFile)"]
span Upload

a.cancel-img.img-upload [href="#" ng-click="cancel()"]
span Cancel

this code works on a normal html page. But the problem seems to be it cannot listen to the
part of the
. does anyone know how using a modal, I can handle these types of events? I have seen that I might have to wrap some logic in the
function, but i'm not sure what it's expecting.

Any help would be appreciated :)

Answer Source

Based on your results, I would approach this problem by wiring up the event in the onShowing or onComplete event for the dialog. I would create a callback function here:

    locals: {
      p: $scope.persona
    controller: 'ImagesController',
    templateUrl: 'application/views/images/image_modal.html',
    parent: angular.element(document.body),
    targetEvent: ev,
    clickOutsideToClose: true,
    fullscreen: useFullScreen,
    onComplete: wireUpChangeEvent,
    onRemoving: removeChangeEvent // so it doesn't get wired up multiple times

I'm not 100%, but I think the dialog stays on the DOM after you hide(close) it. If that's the case, you either need the onRemoving event function or a check to see if it's already been wired up to prevent multiple firings. The function would be called from the controller that launches the dialog. You may need to make the two of them share the same scope by using the scope option and telling it to preserveScope. I'm also not sure if the template will be loaded and on the DOM the first time onShowing is called, so it's probably safer to use onComplete.