Re: Alert user when they hit the browser back button /forward button /refresh button

1,093 views
Skip to first unread message

Thomas Broyer

unread,
Jan 22, 2013, 4:26:17 AM1/22/13
to google-we...@googlegroups.com


On Monday, January 21, 2013 6:31:12 PM UTC+1, Darsha Sai wrote:
Hi ,

I want to display alert message when user click on browser back button/forward button/refresh buttons if form is dirty.

How to capture  browser back button/forward button in gwt ?

You can't. You can only react to navigation, either within the app (History.addValueChangeHandler) or out of the app (Window.addWindowClosingHandler).
There are APIs that wrap them both though: adding a PlaceChangeRequestEvent.Handler to the eventbus if you use the PlaceController, or implementing mayStop() in your activity if you use activities.

Darsha Sai

unread,
Jan 24, 2013, 10:12:43 AM1/24/13
to google-we...@googlegroups.com
Hi Thomas,

Thanks for your response.

I am not using MVP .I am not using  PlaceController . So I only relay on  History.addValueChangeHandler. 

What problem I am facing is ...

In GWT have History ,HistoryImpl classes. 

HistoryImpl class have newItem() , newItemOnEvent() these two  final methods will change the $wnd.location.hash value when we click on browser back button.

Moreover, GWT have different HistoryImpl   classes for browser specific  and  contain native methods to update the $wnd.location.hash .
Like under package com.google.gwt.user.client.impl

HistoryImpl
HistoryImplIE6
HistoryImplMozilla
HistoryImplSafari
HistoryImplTimer


For Example : In Mozilla browser , if I click on browser back button,control is going to  HistoryImplMozilla (see below GWT implementation in History.gwt.xml) and change the the browser URL in "nativeUpdate" method  and then control will come to   History.addValueChangeHandler (onValueChange())   at this time the browser URL already modified and difficult to get the original URL from here.

History.gwt.xml

  <!-- Mozilla has a slightly different history implementation than the     -->
  <!-- standard case.                                                       -->
  <replace-with class="com.google.gwt.user.client.impl.HistoryImplMozilla">
    <when-type-is class="com.google.gwt.user.client.impl.HistoryImpl"/>
    <any>
<when-property-is name="user.agent" value="gecko1_8"/>
<when-property-is name="user.agent" value="gecko"/>
</any>
  </replace-with>

How to show the alert message  in this time ? in Alert message if user clicks to NO button means wants to stay in same page then its difficult to get the original URL . because original URL already modified.

In which place is suitable for showing Alert message to the user  if form is dirty and clicks on browser back button.

Its difficult to customize the HistoryImpl class for newItem() , newItemOnEvent() these are final methods can't over ride in sub classes. If i do that (copy entire class and done the customize) I need to customize History ,HistoryImpl ,HistoryImplIE6,HistoryImplMozilla , HistoryImplSafari ,HistoryImplTimer.

Can you please suggest the best way to handle this problem ?

Thanks

Thomas Broyer

unread,
Jan 24, 2013, 10:37:06 AM1/24/13
to google-we...@googlegroups.com


On Thursday, January 24, 2013 4:12:43 PM UTC+1, Darsha Sai wrote:
Hi Thomas,

Thanks for your response.

I am not using MVP .

activities != MVP (see "debunking misconceptions" at http://tbroyer.posterous.com/gwt-21-places)
 
I am not using  PlaceController . So I only relay on  History.addValueChangeHandler. 

What problem I am facing is ...

In GWT have History ,HistoryImpl classes. 

HistoryImpl class have newItem() , newItemOnEvent() these two  final methods will change the $wnd.location.hash value when we click on browser back button.

Moreover, GWT have different HistoryImpl   classes for browser specific  and  contain native methods to update the $wnd.location.hash .
Like under package com.google.gwt.user.client.impl

HistoryImpl
HistoryImplIE6
HistoryImplMozilla
HistoryImplSafari
HistoryImplTimer


For Example : In Mozilla browser , if I click on browser back button,control is going to  HistoryImplMozilla (see below GWT implementation in History.gwt.xml) and change the the browser URL in "nativeUpdate" method  and then control will come to   History.addValueChangeHandler (onValueChange())   at this time the browser URL already modified and difficult to get the original URL from here.

History.gwt.xml

  <!-- Mozilla has a slightly different history implementation than the     -->
  <!-- standard case.                                                       -->
  <replace-with class="com.google.gwt.user.client.impl.HistoryImplMozilla">
    <when-type-is class="com.google.gwt.user.client.impl.HistoryImpl"/>
    <any>
<when-property-is name="user.agent" value="gecko1_8"/>
<when-property-is name="user.agent" value="gecko"/>
</any>
  </replace-with>

How to show the alert message  in this time ? in Alert message if user clicks to NO button means wants to stay in same page then its difficult to get the original URL . because original URL already modified.

In which place is suitable for showing Alert message to the user  if form is dirty and clicks on browser back button.


You have basically two solutions:
  • globally; you'll have to somehow ask the "current form" whether it's dirty or not and depending on that display a confirm message
  • at the form level; addValueChangeHandler when the form is displayed, removeHandler when navigating away
In any case, you can either live with the history token no longer representing your current "place" (see https://code.google.com/p/google-web-toolkit/issues/detail?id=6726) or track the current token and issue a History.newItem() when you want to "cancel" the navigation to "reinstall" the current token.
 
Its difficult to customize the HistoryImpl class for newItem() , newItemOnEvent() these are final methods can't over ride in sub classes. If i do that (copy entire class and done the customize) I need to customize History ,HistoryImpl ,HistoryImplIE6,HistoryImplMozilla , HistoryImplSafari ,HistoryImplTimer.

These are implementation details, you don't need to (and shouldn't) mess with them.

Jens

unread,
Jan 24, 2013, 10:45:43 AM1/24/13
to google-we...@googlegroups.com
When your form is dirty and the user hits the back button your History.addValueChangeHandler is called. Then you show the Window.confirm() message and when the user hits NO, you simply do not react and stay on your current place inside your app. Of course your URL hash fragment is wrong now as the browser has changed it automatically (you can't do anything against it, even not in the HistoryImpl classes). 

You could correct the wrong hash fragment by calling History.forward() and do nothing on the resulting History.addValueChangeHandler call as you have not changed your place in your app. So you need to remember where you are and you have to remember that independently of what the URL hash fragment looks like.

I do something similar with GWT Places. When a user is at Place1 and manually changes the URL hash fragment to something that represents Place2 the app would go to Place2. But if the user does not have the permission to access Place2 the app will not go there and stay at Place1. Instead it will show a Window.alert() message and after that it calls History.back() to change the hash fragment back to what it was before the user has modified it manually. As the application is still at Place1 and History.back() would go back to Place1 nothing will happen. This works pretty well and is done using a custom PlaceController.

-- J.




Reply all
Reply to author
Forward
0 new messages