question about PrettyNavigationHandler, how can I configure and use it properly.

Splash Forums PrettyFaces Users question about PrettyNavigationHandler, how can I configure and use it properly.

This topic contains 7 replies, has 3 voices, and was last updated by  nicmon 5 years, 3 months ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #18500

    nicmon
    Participant

    I’m using the Primefaces DataTable to show a list of results. after clicking on one row, the page must be forwarded to another page to show the detailed information belong to that row (record).

    here are my codes:

    faces-config.xml

    <navigation-rule>
    <from-view-id>/pages/*</from-view-id>
    <navigation-case>
    <from-outcome>resultPage</from-outcome>
    <to-view-id>/pages/results/resultPage.xhtml</to-view-id>
    </navigation-case>
    </navigation-rule>

    <navigation-rule>
    <from-view-id>/pages/results/resultPage.xhtml</from-view-id>
    <navigation-case>
    <from-outcome>detail</from-outcome>
    <to-view-id>/pages/userRequestDetailPage.xhtml</to-view-id>
    </navigation-case>
    </navigation-rule>

    <lifecycle>
    <phase-listener>com.ocpsoft.pretty.faces.event.MultiPageMessagesSupport</phase-listener>
    </lifecycle>

    pretty-config.xml

    <url-mapping id="results">
    <pattern value="/results" />
    <view-id value="/pages/results/resultPage.xhtml" />
    </url-mapping>

    <url-mapping id="detail">
    <pattern value="/detail" />
    <view-id value="/pages/userRequestDetailPage.xhtml" />
    </url-mapping>

    ManagedBean

    public void onRowSelect(SelectEvent event) {
    final FacesContext context = FacesContext.getCurrentInstance();
    final ConfigurableNavigationHandler handler = (ConfigurableNavigationHandler) context.getApplication().getNavigationHandler();
    this.selectedUserRequest = (UserRequest) event.getObject();

    final PrettyNavigationHandler prettyNavigationHandler = new PrettyNavigationHandler(handler);
    prettyNavigationHandler.performNavigation("pretty:detail");
    }

    the problem is that the above code doesn’t work at all, if I change “pretty:detail” to “detail”, the page will be forwarded to desired detail page, but the url remains “/results” (and not the expected “/detail”).

    Thank you for your help.

    #22771

    Hi,

    there are a number of things in your example that are very uncommon:

    1. You typically don’t need any navigation rules in your faces-config.xml if you are using PrettyFaces.

    2. Your mapping for the detail page doesn’t contain any path parameter to identify which record is viewed. This isn’t very RESTful. If for example a user reload the detail page (via F5 or by using a bookmark), your application cannot know which is the “current record”.

    3. Invoking the NavigationHandler directly is also very uncommon.

    Perhaps you should have a look at this post I wrote some time ago. It contains a general description how to implement the typical CRUD scenario with PrettyFaces:

    Prettyfaces + Hibernate + Spring lazy initialization

    Feel free to ask any question you have regarding the example. :)

    Christian

    #22772

    You should add the <redirect/> element to your navigation config.

    #22773

    nicmon
    Participant

    really appreciate for prompt responses. I’ve changed my application to work like sample CRUD. Also thrown out the navigation-rules from faces-config.xml.

    everything almost works, the only thing is that I want to have my action triggers on RowSelect Event on DataTable and not a link in an extra column (the Link has worked properly as well).

    so if I have these lines on my results page:

    <p:dataTable value="#{searchForm.userRequests}" var="userRequest" rowKey="#{userRequest.id}" liveScroll="true" rows="25" 		        					 selectionMode="single" selection="#{userRequestResultBean.selectedUserRequest}">

    <p:ajax event="rowSelect" listener="#{userRequestResultBean.onRowSelect}" />

    <p:column>
    <pretty:link mappingId="userRequestDetail">
    <f:param value="#{userRequest.id}" />
    Edit
    </pretty:link>
    </p:column>

    and these in RowSelect Event Handler:

    public void onRowSelect(SelectEvent event) throws IOException {
    this.selectedUserRequest = (UserRequest) event.getObject();

    final FacesContext context = FacesContext.getCurrentInstance();
    final ExternalContext externalContext = context.getExternalContext();
    externalContext.redirect("/pages/userRequestDetailPage.xhtml");
    }

    it doesn’t work, as it expects a parameter which we pass by using f:param, but how can I specify the parameter here?

    the target bean looks like this:

    @Controller
    @Scope(WebApplicationContext.SCOPE_REQUEST)
    @Data
    @URLMapping(id = "userRequestDetail", pattern = "/userRequestDetail/#{userRequestDetailBean.id}", viewId = "/pages/userRequestDetailPage.xhtml")
    public class UserRequestDetailBean {
    private Integer id;

    private UserRequest userRequest;

    @Resource
    private UserRequestInventoryService userRequestInventoryService;

    @URLAction
    public void init() {
    userRequest = userRequestInventoryService.readUserRequest(id);
    }

    }

    Thanks again.

    #22774

    I’m not 100% sure that my suggestion works, because I never tried it in such a scenario, but you could try this. Change you pattern to this:

    pattern = "/userRequestDetail/#{ id : userRequestDetailBean.id }"

    and then redirect like this:

    externalContext.redirect( "/pages/userRequestDetailPage.xhtml?id=" + id );

    Another option would be to inject the UserRequestDetailBean into the userRequestResultBean and then set the ID before doing the redirect:

    public class UserRequestResultBean {

    @Autowire
    private UserRequestDetailBean detailBean;

    public void onRowSelect(SelectEvent event) throws IOException {

    // ...
    detailBean.setId( id );
    externalContext.redirect( "/pages/userRequestDetailPage.xhtml" );

    }

    }

    I hope this helps :)

    #22775

    nicmon
    Participant

    Thank you, I preferred your first solution, but I had to enter the base url to make it work.

    so this is how the code looks like:

    @URLMapping(id = "userRequestDetail", pattern = "/userRequestDetail/#{userRequestId : userRequestDetailBean.id}", viewId = "/pages/userRequestDetailPage.xhtml")

    and

    externalContext.redirect(externalContext.getRequestContextPath() + "/pages/userRequestDetailPage.xhtml?userRequestId=" + getSelectedUserRequest().getId());

    the problem is that the URL will not be resolved to pattern and remains “/WebPortal/pages/userRequestDetailPage.xhtml?userRequestId=7”

    Shall I use a rewrite rule there or I’m overseeing something?

    #22776

    Ah, OK, I forgot. If you send a redirect directly this way, the URL won’t be rewritten. What you would have to do is call HttpServletRequest.encodeURL() before sending the redirect.

    But in this case it may be easier for you to just directly build the desired URL for the redirect, something like:

    externalContext.redirect( externalContext.getRequestContextPath() + "/userRequestDetail/" + getSelectedUserRequest().getId() );

    #22777

    nicmon
    Participant

    thank you, works perfectly.

Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.

Comments are closed.