Note that there are some explanatory texts on larger screens.

plurals
  1. PORequest scoped page navigation
    primarykey
    data
    text
    <p>I am designing a site using standard Java EE components like JSF 2.0, CDI, EJB and JPA. It is in its early stages so the navigation is quite simple. The problem is that I have difficulties to retain some data when navigating.</p> <p>Here is the <code>seminarController</code> backing bean:</p> <p><code>SeminarController.java</code></p> <pre><code>@Named @RequestScoped public class SeminarController { @Inject private SeminarDao seminarDao; private int seminarID; private Seminar seminar; ... // Getters and setters ... public Collection&lt;Seminar&gt; getSeminars() {...} public Collection&lt;Seminar&gt; getUpcomingSeminars() {...} public void initSeminar() { seminar = seminarDao.findSeminar(seminarID); } public String save() { seminarDao.save(seminar); return "details"; } } </code></pre> <p>The first page is currently just listing some seminars that are upcoming and might be of interrest.</p> <p><code>index.xhtml</code></p> <pre><code> &lt;ul&gt; &lt;ui:repeat value="#{seminarController.upcomingSeminars}" var="seminar"&gt; &lt;li&gt; &lt;h:link value="#{seminar.title}" outcome="details"&gt; &lt;f:param name="id" value="#{seminar.seminarID}"/&gt; &lt;/h:link&gt; on &lt;h:outputText value="#{seminar.eventDate}"/&gt; &lt;/li&gt; &lt;/ui:repeat&gt; &lt;/ul&gt; </code></pre> <p>As you can see I have a list with links that will take me to the details page if I click the link. I am using <code>f:param</code> to add the id of the seminar to the HTTP Request parameters.</p> <p>The details page show some more details (of course) about the upcoming seminar. The seminar can also be edited by clicking the link.</p> <p><code>details.xhtml</code></p> <pre><code>&lt;f:metadata&gt; &lt;f:viewParam name="id" value="#{seminarController.seminarID}"/&gt; &lt;f:event type="preRenderView" listener="#{seminarController.initSeminar}"/&gt; &lt;/f:metadata&gt; &lt;ui:define name="body"&gt; &lt;h2&gt;#{seminarController.seminar.title}&lt;/h2&gt; &lt;p&gt; &lt;strong&gt;When:&lt;/strong&gt; #{seminarController.seminar.eventDate} &lt;/p&gt; &lt;p&gt; &lt;strong&gt;Where:&lt;/strong&gt; #{seminarController.seminar.address}, #{seminarController.seminar.country} &lt;/p&gt; ... &lt;p&gt; &lt;h:link value="Edit" outcome="edit"&gt; &lt;f:param name="id" value="#{seminarController.seminarID}"/&gt; &lt;/h:link&gt; | &lt;h:link value="Back to List" outcome="index"/&gt; &lt;/p&gt; </code></pre> <p>So far so good, everything works fine.</p> <p>Now we follow the link to edit the seminar and we go to the edit page. We are still using <code>f:param</code> for the id of the current seminar.</p> <p><code>edit.xhtml</code></p> <pre><code>&lt;f:metadata&gt; &lt;f:viewParam name="id" value="#{seminarController.seminarID}"/&gt; &lt;f:event type="preRenderView" listener="#{seminarController.initSeminar}"/&gt; &lt;/f:metadata&gt; &lt;ui:define name="body"&gt; &lt;h:form&gt; &lt;h:messages title="Please correct the errors and try again."/&gt; &lt;fieldset&gt; &lt;h:panelGroup class="editor-label" layout="block"&gt; &lt;h:outputLabel value="Seminar Title:" for="title"/&gt; &lt;/h:panelGroup&gt; &lt;h:panelGroup class="editor-field" layout="block"&gt; &lt;h:inputText id="title" value="#{seminarController.seminar.title}"/&gt; &lt;h:message for="title" title="*"/&gt; &lt;/h:panelGroup&gt; ... &lt;p&gt; &lt;h:commandButton value="Save" action="#{seminarController.save}"&gt; &lt;f:param id="id" value="#{seminarController.seminar.seminarID}"/&gt; &lt;/h:commandButton&gt; &lt;/p&gt; &lt;/fieldset&gt; &lt;/h:form&gt; </code></pre> <p>This is where I am starting to have problems. I want to go back to the details page when the Save button is pressed. The details page should show the current seminar with the newly updated details. The problem is that when the Save button is pressed the <code>seminar</code> object in the <code>seminarController</code> is <code>null</code>.</p> <p>When the edit view is rendered the seminar object is initialized and used to display the current values in the form. But when the Save button is pressed the seminar object no longer exists in the <code>seminarController</code>. And the <code>initSeminar</code> method is not called either.</p> <p>So the question is how should I design the design-edit-design page navigation?</p> <p>ViewScope would not work since I am navigating away to a new view when pressing Save. And ViewScope does not exist when using CDI anyhow.</p> <p>Any help would be grateful!</p> <hr> <p><strong>Edit</strong></p> <p>The Seminar class has some fields that will not be seen in the form.</p> <p><code>Seminar.java</code></p> <pre><code>@Entity public class Seminar { @Id private int seminarID; @Column private String title; @Column private Date eventDate; // Date when the seminar occurs @Column private Date createdDate; // Not visible in forms ... // Some more fields and Getters/Setters } </code></pre> <hr> <p><strong>Edit2:</strong></p> <p>I ended up doing this in the <code>SeminarController</code>:</p> <p><code>SeminarController.java</code></p> <pre><code>@PostConstruct public void init() { if (FacesContext.getCurrentInstance().isPostback()) { seminar = new Seminar(); } else { seminar = seminarDao.findSeminar(seminarID); } } public void setSeminarID(int seminarID) { if (this.seminarID != seminarID) { seminar = seminarDao.findSeminar(seminarID); this.seminarID = seminarID; } } public String save() { seminarDao.save(seminar); return "details?faces-redirect=true&amp;includeViewParams=true"; } </code></pre> <p>And then I added the <code>&lt;h:inputHidden value="#{seminarController.seminarID}"/&gt;</code> to the <code>edit.xhtml</code>.</p> <p>The <code>&lt;f:event/&gt;</code> has been changed accordingly in <code>details.xhtml</code> and <code>edit.xhtml</code> to call the <code>init()</code> method instead of the old <code>initSeminar()</code>.</p> <p>This seems to work although I do not really like that the <code>seminar</code> object is created using <code>new</code> in the post-back and then it is overwritten when the <code>seminarID</code> is being set.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload