1 2 Previous Next 21 Replies Latest reply on Jul 9, 2013 9:00 AM by holsen

    Navigate @Page with pass parameters

    lunserv

      Hello!

      I start with Errai. @Page is very cool for navigation, but how I can pass parameters and extracting them? (e.g. http://example.com#!search;q=some - on page search get param q with value some)?

        • 1. Re: Navigate @Page with pass parameters
          jfuerth

          Great question--this is something we intend to address before the upcoming 2.2 release candidate.

           

          The rough plan is to enhance the existing API by allowing TransitionTo.go() to accept either a MultiMap<String,String> or a varargs array of Strings (which would be a simpler API, but would limit you to positional parameters instead of named parameters).

           

          Alternatively, we've thought about allowing you to create a special page state object that we could marshal into the URL with Errai Marshalling. This would make for a really nice typesafe API, but it would make the URLs themselves quite ugly. We could also do something lighter weight where the page state object would be limited to having only properties of the JSON types (String, Number, Boolean, and lists of those three). This would allow nice nav state tokens, but it puts constraints on the design of the page state objects. :-/

           

          What do you think? String array? Multimap? Typed object?

           

          -Jonathan

          • 2. Re: Navigate @Page with pass parameters
            jdestef

            I think the MultiMap would work fine for many cases.

             

            Thanks

            • 3. Re: Navigate @Page with pass parameters
              lunserv

              Thanks.

              I think MultiMap or object for nice typesafe.

              • 4. Re: Navigate @Page with pass parameters
                eric.wittmann

                +1 for MultiMap

                • 5. Re: Navigate @Page with pass parameters
                  n3k0

                  I would like something like

                   ... either a MultiMap<String,String> or a varargs array of Strings ....
                  

                   

                  In the case of we want to send one or two parameters, a varargs could be useful and quick :-)

                  And in the case of ... i don't know more values, we can use the MultiMap.

                   

                  Greetings.

                  • 6. Re: Navigate @Page with pass parameters
                    jfuerth

                    Thanks for your input, everyone! I decided to go with a hybrid approach. A Multimap<String,String> is available, but the navigation framework can update specially annotated fields with new values from the URL, so you shouldn't normally have to touch the Multimap directly. I also added some lifecycle methods that tell you when the page is showing and hiding so you know when to read those fields and/or do setup and cleanup.

                     

                    I've pushed this new feature to the master branch, so you should be able to use it on the latest 2.2.0-SNAPSHOTs.

                     

                    Have a look at the JavaDoc in the newly-added @PageState, @PageShowing, and @PageHiding annotations. That should give you all you need to get started.

                     

                    Please let me know if you need more info or if this is not going to work for your use cases.

                     

                    -Jonathan

                    • 7. Re: Navigate @Page with pass parameters
                      lunserv

                      very nice!

                      • 8. Re: Navigate @Page with pass parameters
                        eric.wittmann

                        This is great, thanks Jonathan.  I noticed a couple of things when I tried it out, so I went ahead and submitted a pull request with some changes:

                         

                        https://github.com/errai/errai/pull/16

                         

                        1) The full history token is now used when navigating

                        2) The toString on the HistoryToken class wasn't adding the param separator char (&)

                        3) I added a "value()" to the @PageState to provide a way to map query param names to field names.  This allows them to be different (e.g. if I want to ensure that my query param names are all as short as possible, but I want my Java field names to be descriptive).

                         

                        And now I just realized that I tested #1 and #2 and got excited, resulting in Premature Pull Request Syndrome.  I'll go test my changes for #3 now...

                        • 9. Re: Navigate @Page with pass parameters
                          jfuerth

                          Thanks Eric! Much appreciated.

                           

                          I merged your pull request this morning and subsequently committed tests for both of the fixes plus the new feature.

                           

                          -Jonathan

                          • 10. Re: Navigate @Page with pass parameters
                            holsen

                            Had a look at it today. I'm now wondering how to exchange POJOs between those pages?

                             

                            I have a form which consits of 4 pages and I don't want to let those pages exchange information through URL parameters.

                             

                            Also, how do I detect if the url contains now URL parameter? Using Window.Location.getParameterMap(); ? In that case I'd like to send people back to the start page

                            • 11. Re: Navigate @Page with pass parameters
                              jfuerth

                              Chris,

                               

                              The page-to-page navigation in Errai is done by manipulating the DOM, not by actually causing the browser to navigate away from the current page. To pass data from one page to another "behind the scenes," just stick it in an @ApplicationScoped bean which you inject into each of your @Page widgets. The data will persist for as long as the user keeps the browser tab open.

                               

                              If you want the data to persist within the client even longer than that (i.e. across page refreshes, from one day to the next, etc) then you can use ErraiJPA, which will put the data in the browser's localStorage facility. Simply @Inject an EntityManager, persist and flush an entity on one page, and then query it back on the next page.

                               

                              -Jonathan

                              • 12. Re: Navigate @Page with pass parameters
                                holsen

                                Hi Jonathan,

                                 

                                great, that just works like a charm. Is it also possible to combine an @ApplicationScoped Object and a DataBinder?

                                In my example the myData.text String is always empty when it reaches Page2. However, when is manually insert the Data on Page1
                                myData = dataBinder.getModel().getText(); the Data is passed to Page2. Here's my code:

                                 

                                @Templated("#template")

                                @Page(startingPage=true)

                                public class Page1 extends Composite{

                                 

                                    @Inject @AutoBound DataBinder<MyData> dataBinder;

                                    @Inject MyData myData;

                                 

                                    @Inject TransitionTo<Page2> buttonClicked;

                                 

                                    @Inject @DataField Button button;

                                    @Inject @Bound @DataField TextBox text;

                                 

                                    @EventHandler("button")

                                    public void selectNext(ClickEvent e) {

                                        GWT.log(dataBinder.getModel().getText());

                                        myData=dataBinder.getModel();

                                        buttonClicked.go();

                                    }

                                }

                                 

                                @Page

                                @Templated("#template")

                                public class Page2 extends Composite{

                                 

                                    @Inject @AutoBound DataBinder<MyData> dataBinder;

                                    @Inject MyData myData;

                                 

                                    @Inject @DataField @Bound Label text;

                                 

                                    @PageShowing

                                    public void pageShowing()  {

                                        dataBinder.setModel(myData, InitialState.FROM_MODEL);

                                    }

                                }

                                 

                                @Bindable

                                @ApplicationScoped

                                public class MyData {

                                 

                                    String text;

                                 

                                    public String getText() { return text; }

                                 

                                    public void setText(String text) { this.text = text; }

                                 

                                }

                                 

                                @EntryPoint

                                public class App {

                                 

                                    @Inject

                                    private Navigation navigation;

                                 

                                    @PostConstruct

                                    public void buildUI() {

                                 

                                        RootPanel.get().add(navigation.getContentPanel());

                                    }

                                }

                                • 13. Re: Navigate @Page with pass parameters
                                  jfuerth

                                  Yes, if you @Inject an @ApplicationScoped bean into Page1, it should be the same one as injected into Page2. Do you have a similar @PageShowing method in Page2 which sets the model in its DataBinder?

                                  • 14. Re: Navigate @Page with pass parameters
                                    holsen

                                    The forum software somehow managed to hide my Page2. I Just updated the code in my previous post. Yes, Page2 sets the MyData object into the DataBinder. However, the MyData object that Page2 reaches is always empty. Any ideas? Thanks in advance!

                                    1 2 Previous Next