2 Replies Latest reply on Jul 9, 2007 6:30 AM by pmuir

    Injection of NULL immediately after outjection

    dkane

      Hello

      I have implemented a checkbox column for table multi-select, like in dvd store example.
      When list is being updated (e.g.record is being removed), all checkboxes becomes unchecked with no depend on their previous state. I want checked positions to stay checked.

      XHTML (action and checkbox are in bold):

      
      <a:outputPanel id="cartPanel" rendered="#{cartList.rowCount>0}">
      <div class="section">
       <h:form id="createOrder">
       <h1>Shopping cart</h1>
       <h:dataTable value="#{cartList}" var="item">
       <h:column>
       <f:facet name="header">Quantity</f:facet>
       <h:inputText value="#{item.quantity}" style="width: 30px;"/>
       </h:column>
       <h:column>
       <f:facet name="header">Name</f:facet>
       #{item.part.description}
       </h:column>
       <h:column>
       <s:link id="cancel" value="Remove" action="#{cart.removeSelectedPosition}" reRender="cartPanel"/>
       </h:column>
       <h:column>
       <h:selectBooleanCheckbox value="#{cartSelections[item]}"/>
       </h:column>
      
       </h:dataTable>
      
       <h:commandButton id="createOrderBtn" value="Create order" action="#{createOrder.createOrder}"/>
      


      Shopping cart code (I have added some debug code for injection-outjection) :
      package com.avtohouse.ejb;
      
      import java.util.List;
      import java.util.ArrayList;
      import java.util.Map;
      import java.util.HashMap;
      import javax.ejb.Remove;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.*;
      import org.jboss.seam.ScopeType;
      import java.io.Serializable;
      import org.jboss.seam.annotations.datamodel.DataModel;
      import org.jboss.seam.annotations.datamodel.DataModelSelection;
      import org.jboss.seam.annotations.security.Restrict;
      
      import javax.ejb.Stateful;
      
      
      @Stateful
      @Name("cart")
      @Scope(ScopeType.SESSION)
      @Restrict("#{identity.loggedIn}")
      
      public class ShoppingCartBean implements ShoppingCart, Serializable
      {
       private List<OrderCMP> cartOrderList = new ArrayList<OrderCMP>();
      
       @DataModelSelection
       private OrderCMP selectedPosition;
      
       @In
       UserCMP user;
      
       private Map<OrderCMP, Boolean> cartSelections;
      
      public ShoppingCartBean()
      {
       cartSelections=new HashMap<OrderCMP, Boolean>();
      }
      
      
      @In(required=false)
       public void setCartSelections(Map selection)
       {
       System.out.print("Injected selection = "+selection);
       if (selection==null) return ;
       cartSelections=selection ;
       }
      
       @Out(required=false)
       public Map getCartSelections()
       {
       if (cartSelections==null) cartSelections=new HashMap<OrderCMP, boolean>();
       System.out.print("Outjected selection = "+cartSelections);
       return cartSelections;
       }
      
      public void addPart(PartCMP part, int quantity)
      {
       for (OrderCMP order: cartOrderList)
       {
       if (order.getPart().getPartId()==part.getPartId())
       {
       order.addQuantity(quantity);
       return;
       }
       }
       OrderCMP newOrder= new OrderCMP();
       newOrder.setUserId(user.getUserId());
       newOrder.setPart(part);
       newOrder.setQuantity(quantity);
       cartOrderList.add(newOrder);
      }
      
      public void addPart(PartCMP part)
      {
       this.addPart(part,1);
      }
      
      public void removeSelectedPosition()
      {
       if (selectedPosition!=null) removePart(selectedPosition);
      }
      
      public void removePart(OrderCMP order)
      {
       cartOrderList.remove(order);
      }
      
      @DataModel
      public List<OrderCMP> getCartList()
      {
       return(cartOrderList);
      }
       ............
      



      After clicking "Remove" (removePart method is being called), position is properly removed but log says :

      15:20:07,640 INFO [STDOUT] Injected selection = {}
      15:20:07,640 INFO [STDOUT] Outjected selection = {}
      15:20:07,640 INFO [STDOUT] Injected selection = null

      So the problem is that cartSelections becomes null somehow.
      Will appreciate any hints how to solve this .
      Thanks !









        • 1. Re: Injection of NULL immediately after outjection
          dkane

          I have a working slution now but not sure about it's reliability and performance.

          So I needed list of records in Shopping cart. Records can be added, removed and checked (in special checkbox column). The problem was that all checkboxes resets after add or remove operation.

          In fact records of shopping cart are entity beans that are not yet persisted.
          I have done 2 things :

          1) Added a "checked" boolean field with @Transient annotation to the entity bean class and bound checkbox to that field.

          2) Added ajax4jsf "onchange" ajax support to checkbox, with reRender="cartPanel"

          It turned out that reRender writes boolean property to underlying bean and gets it back to UI.

          Any comments about such solution from experienced guys ?
          Thanks.

          • 2. Re: Injection of NULL immediately after outjection
            pmuir

            As s:link doesn't submit the form, all state of the form is lost. If you use something like h:commandButton the form state (if you are in a conversation) should be held.