5 Replies Latest reply: Nov 6, 2012 11:14 AM by lewarrior22 RSS

    Is there a way to navigate beetwen pages with Errai?

    n3k0 Newbie

      Or... do we have to wait for a GWT official way to do that. Or just we have to use another alternative like gwtpages or gwt-multipage ?

        • 1. Re: Is there a way to navigate beetwen pages with Errai?
          Jonathan Fuerth Master

          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?
            Lincoln Baxter III Master

            GWT 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:

             

            https://github.com/ocpsoft/socialpm/tree/master/gwt/src/main/java/com/ocpsoft/socialpm/gwt/client/local/view/login

            https://github.com/ocpsoft/socialpm/blob/master/gwt/src/main/java/com/ocpsoft/socialpm/gwt/client/local/AppPlaceHistoryMapper.java

             

            This also utilises OCPsoft Rewrite for managing the URL history state and bookmarkability of URLs:

             

            http://ocpsoft.org/rewrite/

            https://github.com/ocpsoft/rewrite/tree/master/integration-gwt

            https://github.com/ocpsoft/socialpm/blob/master/gwt/src/main/java/com/ocpsoft/socialpm/gwt/server/history/HistoryRewriteConfiguration.java

             

            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 Newbie

              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?
                Jonathan Fuerth Master

                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 Newbie

                  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.