5 Replies Latest reply on Nov 6, 2012 11:14 AM by lewarrior22
      • 1. Re: Is there a way to navigate beetwen pages with Errai?
        jfuerth

        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

          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

          1 of 1 people found this helpful
          • 3. Re: Is there a way to navigate beetwen pages with Errai?
            n3k0

            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

              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

                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.