pazabo
pazabo

Reputation: 140

Implementing item edition page in JSF

I am creating a JSF application. I have some items (e.g. products) from database and I want to create a JSF page for editing particular items, that is:

I have a problem with storing/passing id of item being edited. I saw that in sample JSF CarDemo application they store item (car) being viewed in session. I don't want to do this because I want user to be able to edit different elements in separate browser tabs.

I tried several approaches:

The problem I still can't eliminate is that if after editing some item properties I try to save them and validation (e.g. f:validateLength) fails the page is reloaded but id of item being edited is lost. I think it is quite standard task when creating web applications (e.g. user edition, store products edition) so there certainly should be some solution.

Thanks in advance.

Upvotes: 3

Views: 1721

Answers (2)

BalusC
BalusC

Reputation: 1109222

Tomahawk's t:saveState does exactly what you want. Just have something like in your page:

<t:saveState value="#{bean.item.id}" />

or if you want to cover all "uncovered" item values:

<t:saveState value="#{bean.item}" />

If you don't want to add another component library for some unknown reasons (I do recommend Tomahawk though, it adds more flexible components on top of standard JSF implementation, e.g. t:dataList, t:dataTable preserveDataModel="true", t:selectOneRadio layout="spread", t:inputFileUpload, etcetera), then you could also use the standard <h:inputHidden> component to pass hidden parameters from request to request (it renders an <input type="hidden">). One caveat is that you will still lost the values when the validation phase fails. But this can be workarounded by using the component binding instead of the value.

private HtmlInputHidden itemId = new HtmlInputHidden();
private Item item = new Item();

public void editItem() { // Action method when selecting an item for edit.        
    itemId.setValue(item.getId());
}

public void saveItem() { // Action method when saving edited item.
    item.setId((Integer) itemId.getValue());
}

and in the JSF page have the following in the same form:

<h:inputHidden binding="#{bean.itemId}" />

Hope this helps.

Upvotes: 3

McDowell
McDowell

Reputation: 108949

Related info:

See this answer for sample code that allows editing while preserving an ID (the information should still be applicable if you're using JSPs instead of Facelets). See this answer for a few more techniques you might like to make use of. See this answer for the options for preserving the parameter in the URL.


To solve your problem, create a request-scope bean to perform the actions:

//pseudo-stubs
//request scope: #{editor}
public class Editor {
  public Integer getId();
  public void setId(Integer id);
  public String save();
}

(You can add other properties as appropriate.)

Populate the id from the request parameter when you navigate to the page via injection in faces-config:

<managed-bean>
  <managed-bean-name>editor</managed-bean-name>
  <managed-bean-class>foo.Editor</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
    <property-name>id</property-name>
    <property-class>java.lang.Integer</property-class>
    <value>#{param.id}</value> 
  </managed-property>
 //etc

Use a hidden field to preserve the id:

<h:inputHidden value="#{editor.id}" />
<h:commandLink action="#{editor.save}" value="save" />

Any time the form is submitted, this value will be sent; if validation fails, the hidden field will still be rendered with the id value. If validation succeeds, the editor bean will be populated with the id prior to the invocation of save.

Upvotes: 4

Related Questions