GWT History remove item - gwt

is it possible to remove a History item in gwt? What i want to achieve is that in a special case pressing the browsers back button will show up the second history item from back. I know i can do it by manually calling History.back();, but i don't like that because the user will see the transition for a second or so which is not nice. Thx in advance for help.
kuku

No the browsers do not allow this.
GWT uses Javascript (of course) to manipulate the browser history. The Javascript engines do not allow the removal of history entries.
Maybe you could make a HistoryListener to skip the step you want removed, but you would have to keep track of history yourself in order to decide which way to skip (forward or backward)

As stated above, this isn't possible via GWT but you can manage this using History
(note: HistoryListener - mentioned in the previous post - has been deprecated)
Here is a simple example that will get you started.
public class UrlManager implements ValueChangeHandler<String> {
public UrlManager() {
History.addValueChangeHandler(this);
}
public void onValueChange(ValueChangeEvent<String> event) {
String historyToken = event.getValue();
}
}

You can use History.replaceItem(newToken, fireEvent).
This will replace the current history token on top of the browsers history stack.
newToken - history token to replace current top entry
fireEvent - a boolean for whether you want to fire history state event or not

Related

GWT Forward Button

I'm having an issue handling the forward button.
Basically, when a user is on a page and has made changes without saving then presses the backwards or forwards button they are presented with a prompt and two options: Leave or Stay.
I have implemented the backwards button fine, and choosing to stay on the page works well using History.newItem(currentToken) - the back button is still clickable.
However with the forwards button, if I use History.newItem(currentToken), it brings this to the front of the history stack and the forward button can no longer be clicked.
History.replaceItem(currentToken) causes the same issue.
How do I handle the cancelling of a forwards action so that I stay on my current page, but the forwards button is still enabled?
#Override
public void onValueChange(ValueChangeEvent<String> event) {
logger.info("back button pressed: " + event.getValue());
String evenVal = event.getValue();
String token = History.getToken();
AbstractPresenter presenter = sessionKiosk.getCurrentlyShowingPresenter();
if (presenter instanceof NSRCommonWorksheetPresenter && sessionKiosk.isDirty()) {
((NSRCommonWorksheetPresenter)presenter).setHistoryToken(event.getValue());
((NSRCommonWorksheetPresenter)presenter).showUnsavedChangesLeavingPageDialog();
}
else {
handleHistoryEvent(event.getValue());
}
}
The dialog is shown and when I click on stay on page the following is called.
public void stayOnCurrentPage() {
if (eventMap.get(prevPage) != null) {
History.newItem(prevPage, false);
}
}
Update: Basically history.newItem(value) removes the use of the forward button. Is there another way to cancel the event? If I just do nothing, th page stays where i want but the url still updates
None of the 3 options in the else statement seem to work.
Thanks.
You can simply cancel the event without touching History or tokens.
UPDATE:
It appears from your code that you are not intercepting the event (back/forward button), but let it go through, get the new token, and then force a return to the previous state under certain circumstances.
I suggest using Activities and Places pattern where every "place" within your app has a corresponding "activity". Each activity in your app will implement GWT Activity interface which includes mayStop() method. This method is called before a user navigates away from a specific place in your app, giving you an opportunity to warn a user and cancel the navigation if necessary.
In general, this pattern offers a very robust support for the History mechanism, covering many use cases.
If you want to support History mechanism yourself, take a look at PlaceChangeRequestEvent - it allows you to warn a user who tries to navigate away from a place in your app.

Detect Wicket user inactivity

Does anybody have an idea on how I can accomplish this using Wicket?
I want to display a Wicket odal window automatically when no user activity has been detected for a certain amount of time. I'm thinking of using an AjaxSelfUpdatingBehavior in some way, but I have no clear ideas actually.
Is this possible with Wicket?
Also, you can use some js library not to catch all ajax calls and to be sure, that your user is really afk (even does not touching his mouse).
For example, see this free framework and it's demo.
And (if you using this js framework) in wicket you must handle
ifvisible.idle(function(){
Wicket.Ajax.get({u: '${callbackUrl}'})// This code will work when page goes into idle status
});
You must set ${callbackUrl} from wicket code to let js know what action to proceed in java code. It is not hard to do this. Look here.
This approach is more tricky, but if you implement this, you don't have to worry about users actions at all (he can read site's info and don't click any ajax links, but suddenly he will see modal window).
Yes you can, I use this as autologout function
public class MyTimer extends AbstractAjaxTimerBehavior {
public MyTimer(int seconds) {
this(Duration.seconds(seconds));
}
#Override
protected void onTimer(AjaxRequestTarget target) {
// show your window magic
}
}
Add this to you page (add(new MyTimer(300));) and this will be called after the number of seconds you specify. Make sure to replace the timer with a new one when doing ajax calls, or reset it.

GWT MVP without tracking History / ignoring back button

First off, before the flames start, I do know that trying to hinder the back button in the browser is a dumb idea. I would not try to do this, but my business partners are very insistent on it. We are porting an existing .exe to the web and their definition of this is 'run it in a browser' and not "make it a web site". So, fact that it's a bad idea (I agree), here's the question:
Is there a way to ignore or trick the GWT PlaceController / History manager mechanisms so that when the back button is pressed, it just stays on the same page?
I have used Window.addWindowClosingHandler to add a handler which will prompt the user if they want to leave the page and overriden the newItem() method of the defaultHistorian so that no history is tracked at all, but this isn't quite what the business people want.
What they'd like is to just ignore the back button so that nothing happens when it is clicked.
If anyone knows how to do this with GWT, I'd be very grateful.
And I"ve done a lot of google searching and haven't found anything exactly like this question. At least, not close enough to help.
I was able to get GWT to not accumulate any history so that when the user presses the BACK button, they cause an onWindowClosing event to happen and the Browser will prompt them if they want to stay or leave. This will accomplish the goal of not allowing the BACK button to take them back, but it's a bit Draconian. This code does that:
class TvHistorian extends PlaceHistoryHandler.DefaultHistorian
{
#Override
public void newItem(String token, boolean issueEvent) {
// don't do anything - this will prevent history from accumulating
}
}
final PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper, new TvHistorian());
I've tried a bunch of stuff including extending the PlaceController.goTo() to save the "lastNormalFlowPlace". Then, I tried to override the History.onValueChange to use this saved Place if it was different than what the event specified. But I think I missed some subtlety because that didn't work as expected.
With the above exception, my code looks almost exactly like what is documented here: http://www.gwtproject.org/doc/latest/DevGuideMvpActivitiesAndPlaces.html#Putting_it_all_together
I have already posted an answer in the same context.
Please have a look at below links:
promt user on backspace and browser backbutton in gwt
how can i get a prompt on url change
Disable back button in GWT
Try with any option:
History.addValueChangeHandler
WindowClosingHandler
Event.addNativePreviewHandler
$wnd.onbeforeunload
--EDIT--
Sample code: (It's working perfectly fine in Firefox, Chrome as well as IE9)
Note: add below code in the beginning of the onModuleLoad() method.
final String initToken = "Place";
History.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
String token = event.getValue();
if (!initToken.equalsIgnoreCase(token)) {
History.newItem(initToken);
}
}
});
// fire the initial history state.
History.fireCurrentHistoryState();
Note: add checks for other allowed history tokens.

Using GWTs activities and places can I navigate to a previous page without using History.back()?

I am using GWTs Activities and Places pretty much as described on http://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html and it is all working fine.
What I would like to do is from a particular page navigate to the previous page without using History.back() as I don't want to lose the history state. (I have a page where the user performs an action, on success I want to return to the previous page and keep the history state, on the other hand if they cancel I do want to use History.back() as I do want to lose the state).
The only way I can think of to do this is to create my own Place/History tracking code that listens to Place/History change events and makes the previous Place available to me so that I can call placeController.goto(...)
Is there an easier way of doing this? Am I missing something?
The approach I took was to store the history token in code (as suggested). I extended PlaceController and used it to track Place changes on the EventBus. Now everywhere I was using PlaceController I instead use PlaceControllerExt which has a nice previous() method that takes me back to where I came from - but navigates forward and never leaves the application.
public class PlaceControllerExt extends PlaceController {
private final Place defaultPlace;
private Place previousPlace;
private Place currentPlace;
public PlaceControllerExt(EventBus eventBus, Place defaultPlace) {
super(eventBus);
this.defaultPlace = defaultPlace;
eventBus.addHandler(PlaceChangeEvent.TYPE, new PlaceChangeEvent.Handler() {
public void onPlaceChange(PlaceChangeEvent event) {
previousPlace = currentPlace;
currentPlace = event.getNewPlace();
}
});
}
/**
* Navigate back to the previous Place. If there is no previous place then
* goto to default place. If there isn't one of these then it'll go back to
* the default place as configured when the PlaceHistoryHandler was
* registered. This is better than using History#back() as that can have the
* undesired effect of leaving the web app.
*/
public void previous() {
if (previousPlace != null) {
goTo(previousPlace);
} else {
goTo(defaultPlace);
}
}
}
You have to somehow keep track of were to return, because instead of cancel the user can hit the back button, which would be the same as clicking cancel, except there is no code in your application executed, so you have no control.
Secondly if you have the history in the url, the user could navigate directly to that page and then you should know where to go to when the user click ok. Or if the user goes directly to the page, redirect the user to another page.
One approach is to store the return history token in the history token of the page you go to. When the page is finished it can go back(or technically it would be 'go forward') to that page based on the passed return token. (Although with GWT you could easily store the history token in code).

hyperlinks with gwt

I am new to GWT, I would like to use hyperlinks where I would like to redirect the user to another form.
My question is that , creating hyperlinks are easy, but how do I use them ?? addClickListener seems to be deprecated, is there any other way to go around this ?
Update 1
I have implemented the Hyper link code as follows :
Hyperlink link0 = new Hyperlink("Show Boxes","showbox");
History.addValueChangeHandler(this);
History.fireCurrentHistoryState();
public void onValueChange(ValueChangeEvent<String> event) {
String eventValue=event.getValue();
if(eventValue.equals("showbox")){
showBox();
}
}
With this I see that the form corresponding to one hyperlink is visible, but this form is not closed and another for is not being opened when I click one another hyperlink.
I am using DockPanel to display the form in the East direction. The forms for all the hyperlinks are just being displayed one below the other.
Any comments/suggestions for the same ?
Thanks,
Bhavya
Use the Anchor.addClickHandler() method!
Anchor a = new Anchor("text");
a.addClickHandler(new ClickHandler(){
// etc
});
If the another form is within your GWT application, then you should consider using Hyperlink. In constructor you provide a history token which is pushed to History object when link is clicked. You just need to handle event that a history token has changed. It decouples navigation events from your logic. This will also make your application aware of back-forward and allows users save bookmarks to specific state (form in your case). Anchor is intended more for external links.
See it described in Coding Basics - History .
First you need to create a HyperLink with a history token:
Hyperlink link = new Hyperlink("link to foo", "foo");
In above example, "foo" is the history token.
Then you should register your value change handler on History object, like
History.addValueChangeHandler(myValueChangeHandler);
In your value change handler, you will need to read in the current token using event.getValue().
class MyValueChangeHandler implements ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
//get the new value of history token
//clicking on above example link will return "foo" here
String historyToken = event.getValue();
}
}
What does the value of history token means is up to your application to decide. For example you can maintain a simple Map between history tokens and the view that should be rendered. In more sophisticated applications you can encode more details into the token -- like initial state of the form that should be displayed.