Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs $window.open popups being blocked

I am trying to use the Github API's web auth flow from within an AngularJS app. When my signup form submits, I want to open a new window to send them to the the auth page. Normally I would just use window.open inside a user event to ensure it wouldn't get caught by a popup blocker.

In my angular app, I am wrapping a bit of the Github api in and Angular service, and the code to open the window goes in there. Because of that it gets blocked. I also tried putting it in a function in the controller that gets called by a form via ng-submit.

So the question is, is there an elegant way to open a new page on a form submit from somewhere inside my service or controller, or will I need to find another way to do it?

like image 770
giodamelio Avatar asked Oct 21 '13 02:10

giodamelio


People also ask

How do I stop a pop-up window from blocking?

To disable the pop-up blocker, uncheck the Blocked (recommended) box. To enable pop-ups on specific sites, check Blocked (recommended) and click Add next to Allow and enter the URL(s). CHROME (MAC) By default, Chrome will notify you when a pop-up is blocked and give you an option to see it.

How do I disable or disable pop-up blocker programmatically?

Answers. The only way to get around popup blockers is for user activity to directly open the window. This will work most of the time, unless the user has his blocker set to refuse all popups. This application uses JavaScript for its functionality.


3 Answers

Chrome by default blocks popups that are not a result of user's direct action. In your case, I assume, the call to window.open is made inside a callback function. This makes it asynchronous and Chrome blocks it.

//before
$scope.userClicked = function(){
  $http.post('your/api/endpoint',{data:x}).then(function(r){
    $window.open(r.data.url,'window name','width=800,height=600,menubar=0,toolbar=0');
  });
}

However, there is a workaround to make this work. Instantiate your window outside the callback function and you can reference the variable to change the target url of that window in callback function.

//after
$scope.userClicked = function(){
  var popup = $window.open('','window name','width=800,height=600,menubar=0,toolbar=0');
  popup.document.write('loading ...');

  $http.post('your/api/endpoint',{data:x}).then(function(r){
    popup.location.href = r.data.url;
  });
}
like image 111
Nirav Gandhi Avatar answered Oct 13 '22 16:10

Nirav Gandhi


You can't get rid of the popup blocker for scripted automated window.open. Only real user's call to action events will open a new window without being blocked by popup blocker. Imagine a situation in a site where there's no popup blocker in browser and javascript opens 100 popups in a loop. Would you like it ? It used to be there in our old good times like a virus but modern browsers are much smart and this annoyance is handled gracefully.

like image 39
Mahbub Avatar answered Oct 13 '22 18:10

Mahbub


You could quite simply create a directive to do this from within a click event content:

yourapp.directive('awesomeClick', ['$parse',function ($parse): ng.IDirective {
    return {
        restrict: 'A',        
        link: (scope, element:JQuery, attrs) => {
            var fn = $parse(attrs.awesomeClick);
            element.on('click', function (event) {

                // open the window if you want here 

                scope.$apply(function () {
                    fn(scope, { $event: event });
                });
            });
        }
    }
}]);
like image 25
basarat Avatar answered Oct 13 '22 16:10

basarat