hyperlinks with gwt - 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.

Related

GWT: Opening new mail window without browser tab opened

I am trying to open an email client just like using mail me tag.
But I want to use my custom widget, which is not hyperlink, anchor or so. I added a DOM handler to my widget to listen to clicks:
public class VContactWidget extends VHorizontalLayout implements ClickHandler {
private HandlerRegistration clickHandler;
public VContactWidget() {
// added some content here
clickHandler = addDomHandler(this, ClickEvent.getType());
}
#Override
public void onClick(ClickEvent event) {
Window.open("mailto:john.doe#mail.com", "_blank", "");
}
}
Everything is working fine except one detail: When the widget is clicked, new empty browser tab will open with url set to mailto:john.doe#mail.com. I don't want the new tab opened. Can I avoid it somehow?
Note I set _blank parameter, as used in many examples. I also tried to use empty string or some other values as well. I looked into documentation, but didn't find anything useful.
https://developer.mozilla.org/en-US/docs/Web/API/window.open
One solution may be to use Anchor, but my component is more complex, not just single <a> link.
Another detail to note may be application server - I am using Tomcat 7 now.
Trying to fire native event on hidden Anchor programatically did not work for me. (Which does not mean it cannot be done.)
This is, how I actually solved my problem: Instead of Window.open(), I used following call:
public void onClick(ClickEvent event) {
Window.Location.assign("mailto:john.doe#mail.com");
}
This is not something that you can control. Whether this link opens in a new tab or a new window depends on the browser settings and user preferences.
I don't think it will make a difference if you use an Anchor or Window.open. In either case, the behavior may be different in different browsers. Also remember that for some users a click on this link will open Outlook or Mail, while for other users it will open Gmail in a browser window.
UPDATE:
If you want an exact behavior of an <a> element, create a hidden anchor element and fire a click on it when a user clicks on your composite widget.
Firing click event from code in gwt

Can we just let "prepareFromRequest" to behave just like traditional non-Ajax page?

Ok, let see how traditional non-Ajax page work. Suppose you have a page like the below link
abc.com#!search;item=car
In the traditional non-Ajax website, when first time you call "abc.com#!search;item=car", it will go to server and get data. After that you go to other page like "abc.com#!customer;name=tom" and then you hit back button it will go back to "abc.com#!search;item=car". However, this time it won't call to the server again cos it remembered it did before.
Now Here is the GWTP problem. Suppose the above abc.com was built in GWTP technology.
At the first time wen user enters the "abc.com#!search;item=car", the GWTP app will initialize the page "search" via onBind, then the prepareFromRequest will be called & it will go to server to get data.
That is Good, no problem. However, if we open a new page (like customer page) by using revealPlace, then we hit the back button it will go back to "search" page & it will call prepareFromRequest again. The prepareFromRequest will then make the exactly same call to server again. That is not good cos it wastes resource.
So I want the "prepareFromRequest" to be called ONLY at the time we initialise the page (run after onBind) & block the "prepareFromRequest" in all other page request (ex like user press the back button).
It mean "prepareFromRequest" should work just like traditional non-Ajax page mentioned above.
Can we do that? or
Do you have a better solution?
Why don't you just check in your prepareFromRequest method if you have already a search result for that specific searchterm and only issue a call to the backend if it has changed?
Something like this:
public Presenter extends .... {
String searchItem = null;
List<DTO> searchResult = null;
#Override
public void prepareFromRequest(PlaceRequest placeRequest) {
super.prepareFromRequest(placeRequest);
String item = placeRequest.getParameter("item",null));
if (searchItem == null || !searchItem.equals(item)) {
searchItem = item;
// MAKE A CALL TO THE BACKEND AND STORE THE DATA IN A FIELD.
searchResult = GET_FROM_SERVER(searchItem);
}
}
}

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).

GWT History remove item

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

go back to the first form in windows mobile application

i am developing an application in which i have a logout option at all the forms. When i click that button I have to return to login form which is the first form to be displayed . So i am able to track back to the first from by making a new object of this from by the way this idea is bad to implement because the other froms are also in the stack. My question is how will i go to that first form while the other form objects are distroyed.
The whole idea is about login-logout functionality in winMo app. If somebody can help me with some part of code it will be very great.
Regards,
Madhup
The easiest way is to pass a reference to the Log-in form to all other forms. Avoid creating and destroying forms. Since you know you are going to reuse them, create them only once and then show or hide them.
In log-in form:
if (isLoginSuccessfull) {
newForm.SetParentForm(this);
newForm.Show();
// Do not call Close();
}
In secondary-forms:
public void SetParentForm(Form parent) {
this.parent = parent;
}
// When you need to close the form:
parent.Show();