Invoke click event file input after $mdDialog closes

I’m facing a strange behavior trying to invoke a file input by using his click event after close a $mdDialog.

When I invoke the click event without using the $mdDialog everything works fine, but using with the dialog the upload file choose popup never show.

Html code

<input type="file" id="file" ng-hide="true" />

<button ng-click="tryUploadFile($event)" />

JavaScript code

$scope.tryUploadFile = function(event) {
    upload(angular.element(document.body), 'Upload file', 'Cancel', event);
}

function upload(_parent, _okText, _cancelText, _event) {

    if($scope.hasCurrentChanges) {
        confirm = $mdDialog.confirm()
            .parent(_parent)
            .title('Are you sure you want to update?')
            .content('This item is already in use, updates maybe change its behavior.')
            .ariaLabel('Update')
            .ok(_okText)
            .cancel(_cancelText)
            .targetEvent(_event);

            $mdDialog.show(confirm).then(openFileChooser);
    }
    else {
        openFileChooser();
    }
}


function openFileChooser() {
    console.log("invoked");
    // Opens the file selector
    angular.element(document.querySelector('#file')).click();
}

When goes to the else case everything works fine, but when the dialog shows up to confirm users operation the file input doesn’t show.

PS: the function openFileChooser is called correctly in both cases. I put the console.log inside to make sure.

Any one have any idea why this happen?

Thank you guys.

Answer

The reason is that for security reasons browsers will only action a .click() on a file input if the invocation of that .click() occurred from a real click event. If you want to use mdDialog, instead of using a confirm mdDialog you’d need to use a custom mdDialog with a custom action ‘ok/confirm’ button to fire your .click().

Something along the lines of:

$scope.ShowConfirm = function (ev) {
        $mdDialog.show({
           controller: DialogController,
           template: '
            <md-dialog aria-label="Confirm" ng-cloak>
                <md-dialog-content>
                    <div class="md-dialog-content">
                        <p>continue?</p>
                    </div>
                </md-dialog-content>
                <md-dialog-actions layout="row">
                    <span flex></span>
                    <md-button ng-click="cancel()">
                        Cancel
                    </md-button>
                    <md-button ng-click="open()" style="margin-right:20px;">
                        OK
                    </md-button>
                </md-dialog-actions>
        </md-dialog>
            ',
            parent: angular.element(document.body),
            targetEvent: ev,
            clickOutsideToClose: true,
            fullscreen: false
        })
    };
    function DialogController($scope, $mdDialog) {
        $scope.cancel = function () {
            $mdDialog.cancel();
        };
        $scope.open = function () {
            $mdDialog.cancel();
            document.getElementById('inputDialog').click();
        };
    }

Leave a Reply

Your email address will not be published. Required fields are marked *