Reputation: 335
i've wicket panel with list of ProductViews (as SELECT)
after you choose your ProductView from SELECT, its load Product from database by id of ProductView into details form. You can modify Product entity and you can save it when you finish.
After save i try to refresh SELECT list to update its data, but it doesn't work(i mean, for example, SELECT contains an old name of product after rename it, but when i select the same ProductView, it reload an entity into details form again, and of course the new data appears from database) i don't want to reload product list again, i want to solve it from memory. Here is my source:
ProductView:
@Entity
@Table(name = "product")
@XmlRootElement
public class ProductView implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Enumerated(EnumType.ORDINAL)
@Column(name = "category")
private Category category;
public ProductView() {
}
public ProductView(Long id) {
this.id = id;
}
public ProductView(Product product) {
this.id = product.getId();
this.name = product.getName();
this.category = product.getCategory();
}
// + getters & setters
}
Product:
@Entity
@Table(name = "product")
@XmlRootElement
public class Product implements Serializable {
// same as ProductView but more data, objects, connections, etc
}
And wicket panel with comments
private Product product;
private ProductView productView;
private List<ProductView> productViews;
private Form productForm;
private Select categorySelectComponent;
private WebMarkupContainer contentContainer;
public ProductPanel(String id) {
super(id);
setOutputMarkupId(true);
add(contentContainer = new WebMarkupContainer("contentContainer")); // container DIV
contentContainer.setOutputMarkupId(true); // refreshable
contentContainer.add(productForm = new Form("productForm")); // details FORM
contentContainer.add(categorySelectComponent = new Select("categorySelectComponent", new PropertyModel<ProductView>(this, "productView"))); // item SELECT
categorySelectComponent.add( new SelectOptions<ProductView>( // first category
"oneCategory",
new PropertyModel<List<ProductView>>(this, "oneProducts"), // see getOneProducts(); list of productviews
new IOptionRenderer<ProductView>() {
@Override
public String getDisplayValue(ProductView p) {
return p.getName();
}
@Override
public IModel<ProductView> getModel(ProductView p) {
return new Model<ProductView>(p);
}
}));
categorySelectComponent.add( new SelectOptions<ProductView>( // second category
"twoCategory",
new PropertyModel<List<ProductView>>(this, "twoProducts"), // see getTwoProducts();
new IOptionRenderer<ProductView>() {
@Override
public String getDisplayValue(ProductView p) {
return p.getName();
}
@Override
public IModel<ProductView> getModel(ProductView p) {
return new Model<ProductView>(p);
}
}));
categorySelectComponent.add( new SelectOptions<ProductView>( // third category
"threeCategory",
new PropertyModel<List<ProductView>>(this, "threeProducts"), // see getThreeProducts();
new IOptionRenderer<ProductView>() {
@Override
public String getDisplayValue(ProductView p) {
return p.getName();
}
@Override
public IModel<ProductView> getModel(ProductView p) {
return new Model<ProductView>(p);
}
}));
categorySelectComponent.add(new OnChangeAjaxBehavior() { // update form after choose entity
@Override
protected void onUpdate(final AjaxRequestTarget art) {
product = getProductFacade().find( productView.getId() );
updatePanel(art);
}
});
productForm.add(
// some details component (textfields, radios, links, etc) to edit Product
);
productForm.add(new AjaxSubmitLink("formSubmitLink") { // save entity
@Override
protected void onSubmit(AjaxRequestTarget art, Form<?> form) {
super.onSubmit(art, form); // i don't know it is necessary at all
getProductFacade().edit( product );
updateProductViewInCategoryMap(art); // important method
//art.add(contentContainer); //it is in update method
}
});
}
more methods inside panel
private Map<Category, List<ProductView>> categoryMap; // all product by categories
public void initCategoryMap() {
categoryMap = new EnumMap<Category, List<ProductView>>(ProductView.class);
categoryMap.put( Category.ONE, new ArrayList<ProductView>() );
categoryMap.put( Category.TWO, new ArrayList<ProductView>() );
categoryMap.put( Category.THREE, new ArrayList<ProductView>() );
for (ProductView view : getProductViews()) {
categoryMap.get(view.getCategory()).add(view);
}
}
//***** Get Products By Categories *******
final public List<ProductView> getOneProducts(){
if (categoryMap == null){
initCategoryMap();
}
return categoryMap.get( Category.ONE );
}
final public List<ProductView> getTwoCategory(){
if (categoryMap == null){
initCategoryMap();
}
return categoryMap.get( Category.TWO );
}
final public List<ProductView> getThreeProducts(){
if (categoryMap == null){
initCategoryMap();
}
return categoryMap.get( Category.THREE );
}
// **************************************
public List<ProductView> getProductViews() { // Get All Product
if (productViews == null) {
productViews = getProductFacade().findAllProductAsView();
}
return productViews;
}
private void updatePanel(AjaxRequestTarget art) { // refresh panel
art.add(ProductPanel.this);
}
private void updateProductViewInCategoryMap(AjaxRequestTarget art) { // change Product in map after save (call from onSubmit method of AjaxSubmitLink)
for(Map.Entry<Category, List<ProductView>> entry : categoryMap.entrySet()){ // search category contains entity
if (entry.getValue().contains( productView )){
entry.getValue().remove( productView ); // remove entity from category
break;
}
}
productView = new ProductView( product ); // new productview by modified product
categoryMap.get( productView.getCategory() ).add( productView ); // add entity to it's category's list
art.add(contentContainer);
}
and HTML:
<select class="categorySelect" wicket:id="categorySelectComponent">
<optgroup label="Category One">
<wicket:container wicket:id="oneCategory">
<option wicket:id="option"></option>
</wicket:container>
</optgroup>
<optgroup label="Category Two">
<wicket:container wicket:id="twoCategory">
<option wicket:id="option"></option>
</wicket:container>
</optgroup>
<optgroup label="Category Three">
<wicket:container wicket:id="threeCategory">
<option wicket:id="option"></option>
</wicket:container>
</optgroup>
</select>
Any idea?
Upvotes: 0
Views: 505
Reputation: 739
What about updating productViews
on saving changes or using LoadableDetachableModel
instead of PropertyModel
in categorySelectComponent
?
here:
new Select("categorySelectComponent", new PropertyModel<ProductView>(this, "productView")
Upvotes: 1