-
1. Re: Is there a way to navigate beetwen pages with Errai?
jfuerth May 10, 2012 11:41 AM (in response to n3k0)Good question.
At the moment, we don't have anything in Errai for handling page-to-page navigation. If you do try out gwtpages or gwt-multipage, please come back and share your experiences!
-Jonathan
-
2. Re: Is there a way to navigate beetwen pages with Errai?
lincolnthree May 10, 2012 12:27 PM (in response to jfuerth)1 of 1 people found this helpfulGWT Multipage looks like a dead project, but you can also use the MVP (Model View Presenter) pattern from GWT itself:
https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces
Some example code from SocialPM:
This also utilises OCPsoft Rewrite for managing the URL history state and bookmarkability of URLs:
https://github.com/ocpsoft/rewrite/tree/master/integration-gwt
You still have to do link generation yourself, but at least the URLs and bookmarking work at this point. You just need to add a new Activity and Place for each URL you want to expose... typically you also add a new View.
Hope this helps,
Lincoln
-
3. Re: Is there a way to navigate beetwen pages with Errai?
n3k0 Jun 28, 2012 11:35 AM (in response to jfuerth)Challenge accepted ;-)
Ok, ok, sorry about my late reply.
This is my experience with the gwtpages framework, and i'll detail it with a (simplest) example.
First we have to include the gwtpages library to the project classpath, and include its reference in the (The name you like ).gwt.xml
<module rename-to="yourApp"> <inherits name="com.google.gwt.user.User" /> <inherits name="com.google.gwt.user.theme.standard.Standard"/> <inherits name="com.google.gwt.i18n.I18N" /> <inherits name="org.jboss.errai.bus.ErraiBus" /> <inherits name="org.jboss.errai.ioc.Container" /> <inherits name="org.jboss.errai.enterprise.CDI" /> <inherits name="com.google.gwt.gwtpages.GWT_Pages" /> <source path="client" /> <source path="shared" /> </module>
After that, we have to put some .java code to configure gwtpages.
1.- BasePage.java
2.- PageConstants.java
3.- PageLoader.java
4.- MyEntryPoint.java
1.- BasePage.java
This file (like the name says) is the "Base" for the Views that we want to control through gwtpages framework.
This file extends FlowPanel ( it can be SimplePanel too ) and implements Page.
We can to extend this class or implement the Page interface and extends some Panel.
public class BasePage extends FlowPanel implements Page{ @Override public void init(Pages pages) throws Exception {} @Override public void destroy(Pages pages) {} @Override public void onEnterPage(PageParameters parameters, PageRequestSession session, AsyncPageCallback callback) throws Exception {} @Override public void onExitPage() {} @Override public Widget asWidget() { return this; } }
2.- PageConstants.java
This interface is "nice to have", and we will put all the Strings that represents our "pages" in the app.
We can put all the Strings in a, i don't know, an enum or something else ;-)
public interface PageConstants { public static final String DESKTOP_PAGE = "desktopPage"; }
3.- PageLoader.java
This class must extends some "Loader" ( in this example is the AsyncLoader ), in this class, we put the "Pages"
that we want to control by gwtpages framework.
public class PageLoader extends AsyncPageLoader { @Override public void registerPages() { registerPage(PAGE_DEFAULT, Login.class); // don't create a constant PAGE_DEFAULT, just create constants for the other pages, PAGE_DEFAULT is already built =) registerPage(PageConstants.DESKTOP_PAGE, DesktopPage.class); } }
4.-MyEntryPoint.java
This class will be the original EntryPoint in the application, it creates the "Presenter" to our app, paste it to the root
component, inits the PageLoader and shows the first page.
@EntryPoint public class MyEntryPoint { @PostConstruct public void onModuleLoad() { // create the application presenter and add it to the root (this is the simplest of them) SimplePanelApplicationPresenter applicationPresenter = new SimplePanelApplicationPresenter(); RootPanel.get().add(applicationPresenter); // initialize the pages settings Pages.init( (PageLoader) GWT.create(PageLoader.class), applicationPresenter, new HandlerManager(null), true) // we want to listen to history tokens .addDefaultEventHandlers() // add default behavior if desired .showStartPage(true); // show the first page while checking the history token } }
It's all about configure, separately, i have my two "Pages":
Login.java
public class Login extends BasePage implements ClickHandler { private TextBox textBox; private PasswordTextBox passwordTextBox; private Button button; private VerticalPanel verticalPanel; public Login() { this.onModuleLoad(); } public void onModuleLoad() { final DecoratorPanel decoratorPanel = new DecoratorPanel(); final AbsolutePanel absolutePanel = new AbsolutePanel(); absolutePanel.setSize("383px", "237px"); textBox = new TextBox(); absolutePanel.add(textBox, 196, 46); passwordTextBox = new PasswordTextBox(); absolutePanel.add(passwordTextBox, 196, 97); button = new Button("Log in"); button.addClickHandler(this); absolutePanel.add(button, 186, 158); Label lblUsername = new Label("User"); absolutePanel.add(lblUsername, 75, 47); Label lblPassword = new Label("Password"); absolutePanel.add(lblPassword, 75, 98); Label lblRegisteredUser = new Label("Registered users"); absolutePanel.add(lblRegisteredUser, 122, 10); decoratorPanel.add( absolutePanel ); verticalPanel = new VerticalPanel(); verticalPanel.add( decoratorPanel ); verticalPanel.setSize("100%", "100%"); verticalPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); verticalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); verticalPanel.setCellVerticalAlignment(decoratorPanel, HasVerticalAlignment.ALIGN_MIDDLE); verticalPanel.setCellHorizontalAlignment(decoratorPanel, HasHorizontalAlignment.ALIGN_CENTER); this.add(verticalPanel); } @Override public void onClick(ClickEvent event) { if(event.getSource().equals(button)){ String u = textBox.getValue(); String p = passwordTextBox.getValue(); if(u == null || u.isEmpty() || p == null || p.isEmpty() ){ Window.alert("Type a valid username/password"); } else{ this.executeAuthentication(u, p); } } } private void executeAuthentication( final String usr , final String password ){ MessageBuilder.createCall(new RemoteCallback<Long>() { @Override public void callback(Long response) { if( response != null && response > 0 ){ Pages.get().goTo( PageConstants.DESKTOP_PAGE , usr, password ).execute(); //send usr and pass just to show how to send parameters } } }, UserService.class).authenticate( usr , password ); } }
And DesktopPage.java
public class DesktopPage extends BasePage implements ClickHandler { private Label paramLabel; public MonitorDesktop() { add(new Label("The parameters are: ")); add(this.paramLabel = new Label()); } @Override public void onEnterPage(PageParameters parameters,PageRequestSession session, AsyncPageCallback callback) { StringBuilder sb = new StringBuilder(); for (int i=0; i<parameters.listSize(); i++) { if (sb.length() > 0) sb.append(", "); sb.append(parameters.asString(i)); } paramLabel.setText(sb.toString()); } }
As i said, this is a very very simple example of the basic features of the framework, but i don't need anymore, if you want to know more about it, you can go to it's homepage http://code.google.com/p/gwtpages/ to get more info, read the wiki and check the examples.
Note: download the source and compile your own version of gwtpages to work 100% with your version of gwt ( I did with gwt 2.4).
Felices trazos.
I mean, happy coding!
-
4. Re: Is there a way to navigate beetwen pages with Errai?
jfuerth Jun 28, 2012 9:56 AM (in response to n3k0)Wow, thanks!
That's an excellent walkthrough of the gwtpages framework. I'm sure this will be useful to many others.
Glad to see you've got your page navigation up and running!
-Jonathan
-
5. Re: Is there a way to navigate beetwen pages with Errai?
lewarrior22 Nov 6, 2012 11:14 AM (in response to n3k0)Hi, Sorry if It is the wrong place to post.
I'm looking for a way to do achieve this with @Template views. It will be amaizingly good from errai.
@EntryPoint
@Templated("#homeview")
public class HomeView extends Composite{
@Inject
@DataField
private Hyperlink homeLink ;
@Inject
@DataField
private Hyperlink aboutLink ;
@Inject
@DataField
private Hyperlink contactLink ;
@Inject
@DataField
private Button createAccountBtn ;
@Inject
@DataField
private Button loginBtn ;
@DataField
private HTMLPanel main = new HTMLPanel("");
@Inject
private Instance<AboutUsView> aboutUsViewInstance ;
@Inject
private Instance<CreateAccountView> createAccountViewInstance ;
@Inject
private Instance<HomeViewMainContent> mainContentViewInstance ;
@PostConstruct
public void init(){
Window.alert("Initializing ...");
this.main.add(mainContentViewInstance.get());
RestClient.setJacksonMarshallingActive(false);
RootPanel.get("kitchensink").add(this);
}
@EventHandler("aboutLink")
public void onAboutLinkClicked(ClickEvent click){
AboutUsView aboutUsView = aboutUsViewInstance.get();
Window.alert("Initializing ...");
RootPanel rootPanel = RootPanel.get("kitchensink");
rootPanel.clear();
rootPanel.add(aboutUsView);
}
@EventHandler("createAccountBtn")
public void onCreateAccountClicked(ClickEvent click){
Window.alert("Initializing ...");
main.clear();
CreateAccountView createAccountView = createAccountViewInstance.get();
main.add(createAccountView);
createAccountView.setMain(main);
}
public HTMLPanel getMain() {
return main;
}
public void setMain(HTMLPanel main) {
this.main = main;
}
}
//@Page
//@Dependent
@Singleton
@Templated("#createAccountView")
public class CreateAccountView extends Composite {
@Inject
@DataField
private TextBox id ;
@Inject
@Bound
@DataField
private TextBox name ;
@Inject
@Bound
@DataField
private TextBox login ;
//automatically bind account.password to the widget password
@Bound
@Inject
@DataField
private TextBox password;
@Inject
@DataField("webSiteUi")
private TextBox webSite ;
@Inject
@DataField
private TextBox email ;
@Inject
@DataField
private TextBox btnSave ;
@Inject
@AutoBound
private DataBinder<Account> accountDataBinder ;
@Inject
private Event<Account> accountEvent ;
private HTMLPanel main ;
@Inject
private Caller<AccountService> accountServiceCaller ;
@Inject
private Caller<AccountRESTService> accountRestServiceCaller ;
@Inject
private Instance<HomeView> homeView ;
@PostConstruct
public void init(){
accountDataBinder.bind(id, "id");
accountDataBinder.bind(webSite, "website");
}
@EventHandler("btnSave")
public void onBtnSaveClicked(ClickEvent click){
//use the model to retrieve data from the form
Account account = accountDataBinder.getModel();
RemoteCallback<Account> remoteCallback = new RemoteCallback<Account>() {
@Override
public void callback(Account response) {
Window.alert("Account Created from server !"+response);
}
};
ErrorCallback errorCallback = new ErrorCallback() {
@Override
public boolean error(Message message, Throwable throwable) {
if(throwable instanceof TransportIOException){
Window.alert("Could Reach the server : ["+message+"] \n and ["+throwable+"]" );
}else {
Window.alert("Marschalling errors ["+message+"] \n and ["+throwable+"]" );
// kitchensink main_com
RootPanel.get("kitchensink").add(new CreateAccountView());
}
return true;
}
};
// accountServiceCaller.call(remoteCallback,errorCallback).create(account);
// accountRestServiceCaller.call(remoteCallback, errorCallback).create(account);
RestClient.setJacksonMarshallingActive(true);
Window.alert("Save acount "+account+" \n path"+RestClient.getApplicationRoot()+"\n jackson : "+RestClient.isJacksonMarshallingActive());
ResponseCallback responseCallback = new ResponseCallback() {
@Override
public void callback(Response response) {
Window.alert("Account Created from server !"+response.getText());
}
};
RestClient.create(AccountRESTService.class, responseCallback, errorCallback,new Integer[0]).create(account);
// kitchensink main_com
RootPanel.get("kitchensink").add(this);
}
public HTMLPanel getMain() {
return main;
}
public void setMain(HTMLPanel main) {
this.main = main;
}
}
but after every click on the saveBtn, It bring me back to the home view. Do some one has an idea
thanks.