0

I'am building single page using BackboneJS and I need to prevent router executing on back button in a browser. To be exact I need to show confirmation custom popup with the text "Do you really want exit room? [yes|no]". So if user clicks yes then default actions should happens but if no then user should stay in the current screen.

I use Backbone.router with pushState: true. Does Backbonejs provide something like before router event to be possible prevent router handling or how could I archive it?

3
  • duplicate of stackoverflow.com/questions/4184521/… Commented Aug 25, 2015 at 16:10
  • This is not duplicate of because I need to just show custom popup on any route changing with no difference whether on onbeforeunload or click on browser back button Commented Aug 25, 2015 at 21:34
  • sorry, seems like I misunderstood. Please see my answer about a possible way to achieve this. Commented Aug 26, 2015 at 5:04

2 Answers 2

0

I'm not sure if this is still an issue, but this is how I would get around it. It may not be the best way, but could be a step in the right direction.

Backbone.History.prototype.loadUrl = function (fragment, options) { var result = true; if (fragment === void (0) && options === void (0) && this.confirmationDisplay !== void(0)) { result = confirm('Are you sure you want to leave this room?'); } var opts = options; fragment = Backbone.history.fragment = Backbone.history.getFragment(fragment); if (result) { this.confirmationDisplay = true; return _.any(Backbone.history.handlers, function (handler) { if (handler.route.test(fragment)) { //We just pass in the options handler.callback(fragment, opts); return true; } }); } return this; } 

Essentially checking if we have a fragment and options, if not, we can assume the app just started, or the user clicked the back button.

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

1 Comment

Thanks for the response. Could you suggest solution without overriding of internal Backbone API?
0
+50

Backbone router has an execute method which is called for every route change, we can return false to prevent the current transition. The code will probably look like below :

With an asynchronous popup (untested code, but should work)

Backbone.Route.extend({ execute: function(callback,args){ if(this.lastRoute === 'room'){ showPopup().done(function(){ callback & callback.apply(this,args); }).fail(function(){ Backbone.history.navigate('room/486',{trigger:false}); }); }else{ callback && callback.apply(this,args); } }, showPopup: function(){ var html = "<<div><p>Do you really want to exit</p><button id='yes'>Yes</button><button id='no'>No</button></div>" var promise = $.Deferred(); $('body').append(html); $(document).on('click','button#yes',function(){ promise.resolve(); }); $(document).on('click','button#no',function(){ promise.reject(); }); return promise; } }); 

With synchronous confirm popup

Backbone.Route.extend({ execute: function(callback,args){ if(this.lastRoute === 'room'){ var conf = confirm("Do you really want to exit the room ?"); if(!conf){ //Change the route back to room Backbone.history.navigate('room/486',{trigger:false}); return false; } }; callback && callback.apply(this,args); } }); 

References:

http://backbonejs.org/#Router-execute

1 Comment

Thanks for the solution I've thought about it but by my problem is I need to show custom popup (like jQuery popup) which is not asynchronous. So your code is partial solution for my question

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.