cancel
Showing results for 
Search instead for 
Did you mean: 

Checkbox inside a:richList

cybermakoki
Champ in-the-making
Champ in-the-making
Hi all,

I'm desperate, i can't put a checkbox inside alfresco tag richlist, this is my code:

<h:selectBooleanCheckbox id="col19-check" value="#{r['dm:selected']}" />

I'm getting all the time this error:  Base is null: r

It's possible that this could be a bug?

Need help please  Smiley Sad  Smiley Sad  Smiley Sad
18 REPLIES 18

savic_prvoslav
Champ on-the-rise
Champ on-the-rise
That means you have to change the way of checkBox work to ajax .

PS: what you do with selected nodes?

cybermakoki
Champ in-the-making
Champ in-the-making
I do a checkout with the selected nodes.

Pff i have resolved the problem with a h:dataTable, but the content it's not being sorted… i don't know how to sort that Smiley Frustrated

savic_prvoslav
Champ on-the-rise
Champ on-the-rise
Well when I have implemented multiselect I have used ajax and custom checkBox (check JSF custom commands), I have not been able to use the way as you are and to get gmail like multiselect. and I have soloed probelm when all is selected and others that you will see letter.

cybermakoki
Champ in-the-making
Champ in-the-making
ok, thank you for your help anyway… I'll try sorting the content in h:dataTable…

phil_pirozhkov
Champ in-the-making
Champ in-the-making
extend BrowseBean:
public class BrowseBeanEx extends BrowseBean {
    protected static Set<Node> sels = new TreeSet<Node>(new Comparator<Node>() {
        public int compare(Node o1, Node o2) {
            return o1.getId().compareTo(o2.getId());
        }
    });

    public List<Node> getContent() {
        List<Node> list = super.getContent();
        Iterator<Node> it = list.iterator();
        while(it.hasNext())
            it.next().addPropertyResolver("selected", resolover);
       
        return list;
    }

    public boolean isAllSelected() {
        return sels.size() == super.getContent().size();
    }

    public NodePropertyResolver resolover = new NodePropertyResolver() {
        public Object get(Node node) {
            return sels.contains(node);
        }
    };
   
    public void setAllSelected(boolean allSelected) {
        if (isAllSelected() != allSelected) {
            if(allSelected)
                sels.addAll(super.getContent());
            else
                sels.clear();
        }
    }

    public void updateSelection(ActionEvent event) {
        UIActionLink uIActionLink = (UIActionLink) event.getComponent();
        String nodeId = uIActionLink.getParameterMap().get("node_id");
        for(Node node : super.getContent()) {
            if(node.getId().equals(nodeId)) {
                if(sels.contains(node))
                    sels.remove(node);
                else
                    sels.add(node);
            }
        }
        contextUpdated();
    }
}

fix BrowseBean ref in faces-config-beans.xml:

   <managed-bean>
      <description>
         The bean that holds folder browse state.
      </description>
      <managed-bean-name>BrowseBean</managed-bean-name>
      <!–managed-bean-class>org.alfresco.web.bean.BrowseBean</managed-bean-class–>
      <managed-bean-class>com.sap.ca.alfresco.extension.bean.BrowseBeanEx</managed-bean-class>


add to browse.jsp:
   function selectApply(e)
   {
      document.forms['browse']['browse:act'].value='browse:select-apply';
      document.forms['browse']['node_id'].value= e.id;
   if (document.forms['browse']['browse:contentRichListSmiley Tongueager'] != null) {
       document.forms['browse']['browse:contentRichListSmiley Tongueager'].value = document.forms['browse']['browse:contentRichListSmiley TongueagerSmiley TongueageNamber'].value - 1;
   }     
      document.forms['browse'].submit();
      return false;
      
   }

   function selectAll(e) {
   document.forms['browse']['browse:act'].value='';
   if (document.forms['browse']['browse:contentRichListSmiley Tongueager'] != null) {
       document.forms['browse']['browse:contentRichListSmiley Tongueager'].value = document.forms['browse']['browse:contentRichListSmiley TongueagerSmiley TongueageNamber'].value - 1;
   }     
   document.forms['browse'].submit();
   }



<a:actionLink id="select-apply" value="" actionListener="#{BrowseBean.updateSelection}">
<fSmiley Tonguearam name="node_id" value="" />
</a:actionLink>

….

<a:column id="col-sel" style="padding:2px;text-align:left">

<f:facet name="header">
<h:selectBooleanCheckbox id="selectAll" title="Select/Unselect All" value="#{BrowseBean.allSelected}" onclick="selectAll(this);"/>
</f:facet>

<aSmiley Tongueanel id="checkbox_panel">
<f:verbatim>
<%– <h:selectBooleanCheckbox is not available in a rich list (id would be always the same), so need to put html code –%>
<input type="checkbox" id="</f:verbatim><hSmiley SurprisedutputText value="#{r.id}" /><f:verbatim>" </f:verbatim><hSmiley SurprisedutputText value="checked" rendered="#{r.selected}" /><f:verbatim> onclick="selectApply(this);" />
</f:verbatim>
</aSmiley Tongueanel>

</a:column>

phil_pirozhkov
Champ in-the-making
Champ in-the-making
PS fix indentation Smiley Wink

savic_prvoslav
Champ on-the-rise
Champ on-the-rise
you are submiting on each click as I see. not very good idea…

phil_pirozhkov
Champ in-the-making
Champ in-the-making
you are submiting on each click as I see. not very good idea…

Absolutely agree. Below is a working approach which only refreshes a page when "select all" is clicked, which also can be done with no page refresh BTW.

browse.jsp:

<script type="text/javascript">

   <%– LEGTM Selection Box Javascript Begin –%>

   window.onload = onLoad;

   function onLoad()
   {
      var items = document.getElementsByName("browse:chkbox");
      var selected_values = document.getElementById('browse:selectionlist');
      var arr = selected_values.value.split(";");
      if (items != null)
      {
         for (var i = 0; i < items.length; i++)
         {
            var item = items[i];
            var item_selected = false;
            for (var j = 0; j < arr.length; j++)
            {
               if (arr[j] == item.title)
               {
                  item_selected = true
               }
            }
            if (item.checked != item_selected)
            {
               item.checked = item_selected;
            }
            item.title = item.checked ? "Please click to remove from selection" : "Please click to add to selection";
         }
      }
      var selectAll = document.getElementById("browse:selectAll");
      if (selectAll != null) {
          var initialSelectAll = document.getElementById("browse:initialSelectAll");
          selectAll.checked = (initialSelectAll != null);
      }
   }

   function doselect(value, item)
   {
      var selected_values = document.getElementById('browse:selectionlist');
      if (item.checked)
      {
         if (selected_values.value.length != 0)
         {
            selected_values.value = selected_values.value + ";";
         }
         selected_values.value = selected_values.value + value;
         item.title = "Please click to remove from selection";
      }
      else
      {
         var arr = selected_values.value.split(";");
         var new_value = "";
         for (var i = 0; i < arr.length; i++)
         {
            if (arr[i] != "" && arr[i] != value)
            {
               if (new_value.length != 0)
               {
                  new_value = new_value + ";";
               }
               new_value = new_value + arr[i];
            }
         }
         selected_values.value = new_value;
         item.title = "Please click to add to selection";
         var selectAll = document.getElementById('browse:selectAll');
         if (selectAll != null) {
            selectAll.checked = false;
         }
      }
   }

   function selectAll(e)
   {
      document.forms['browse']['browse:act'].value='browse:select-apply-all';
      document.forms['browse']['on_off'].value= e.checked;
      if (document.forms['browse']['browse:contentRichList:pager'] != null)
      {
         document.forms['browse']['browse:contentRichList:pager'].value = document.forms['browse']['browse:contentRichList:pager:pageNamber'].value - 1;
      }     
      document.forms['browse'].submit();
   }

…..

                     <a:actionLink id="select-apply-all" value="" actionListener="#{BatchNavigationBean.setSelectAll}">
                        <f:param name="on_off" id="on_off" value="" />
                     </a:actionLink>
                     <h:inputHidden id="selectionlist" value="#{BatchNavigationBean.selection}" />
                     <h:inputHidden id="initialSelectAll" rendered="#{BatchNavigationBean.allSelected}" />

                     <a:richList id="contentRichList" binding="#{BrowseBean.contentRichList}" viewMode="#{BrowseBean.browseViewMode}" pageSize="#{BrowseBean.pageSizeContent}"
                           styleClass="recordSet" headerStyleClass="recordSetHeader" rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
                           value="#{BrowseBean.content}" var="r">

…..

                        <a:column id="col-sel" style="padding:2px;text-align:left" >
                        <f:facet name="header">
                           <h:selectBooleanCheckbox id="selectAll" title="Select/Unselect All" onclick="selectAll(this);"/>
                        </f:facet>
                        <a:panel id="panel-sel" >
                           <h:selectBooleanCheckbox id="chkbox" value="false" title="#{r.id}" onclick="javascript:doselect('#{r.id}', this);return true;" />
                        </a:panel>
                        </a:column>


Add BatchNavigationBean to faces-config.xml:

   <managed-bean>
      <description>
         Bean used to select nodes on the browse interface
      </description>
      <managed-bean-name>BatchNavigationBean</managed-bean-name>
      <managed-bean-class>your.namespace.BatchNavigationBean</managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
      <managed-property>
         <property-name>navigator</property-name>
         <value>#{NavigationBean}</value>
      </managed-property>
      <managed-property>
         <property-name>browseBean</property-name>
         <value>#{BrowseBean}</value>
      </managed-property>
   </managed-bean>

BatchNavigationBean.java:

class BatchNavigationBean implements Serializable {

   transient private NavigationBean navigator = null;
   transient private BrowseBean browseBean = null;
   private String currentNodeId = null; // reset the selection when the currentNodeId has changed
   private String selection = "";
     
   private static Log logger = LogFactory.getLog(BatchNavigationBean.class);

   public void setSelection(String selection) {
        this.selection = selection;
        if (logger.isDebugEnabled()) {
            logger.debug("Selection set to " + selection);
        }
   }

   public String getSelection() {
        if ( ((currentNodeId == null) != (this.navigator.getCurrentNodeId() == null)) ||
                 ((currentNodeId != null) && !currentNodeId.equals(this.navigator.getCurrentNodeId()))) {
            currentNodeId = this.navigator.getCurrentNodeId();
            selection = "";
        }
      return selection;
   }

    public boolean isAllSelected() {
        return selection.split(";").length == browseBean.getContent().size();
    }

    public void setAllSelected(boolean allSelected) {
        if (isAllSelected() != allSelected) {
            if (allSelected) {
               StringBuffer sb = new StringBuffer();
                for(Node node : browseBean.getContent()) {
                    NodeRef nodeRef = node.getNodeRef();
                        if (sb.length() != 0) {
                            sb.append(";");
                        }
                        sb.append(node.getId());
                }
                selection = sb.toString();
              if (logger.isDebugEnabled()) {
                 logger.debug("Selection set to all nodes");
              }
            } else {
                selection = "";
              if (logger.isDebugEnabled()) {
                 logger.debug("Selection set to no nodes");
              }
            }
        }
    }

    // action to handle "select all" click
    public void setSelectAll(ActionEvent event) {
        UIActionLink uIActionLink = (UIActionLink) event.getComponent();
        boolean allSelected = "true".equals(uIActionLink.getParameterMap().get("on_off"));
        setAllSelected(allSelected);
    }
   
    public Set<NodeRef> getSelected() {
       Set<NodeRef> result = new HashSet<NodeRef>();
       String[] array = selection.split(";");
      StoreRef storeRef = Repository.getStoreRef();
        for (String ref : array) {
           if (ref != null && !ref.isEmpty()) {
                NodeRef nodeRef = new NodeRef(storeRef, ref);
                result.add(nodeRef);
           }
        }
       return result;
    }

    // remove selections from current space e.g. when action was performed
    public void unselectNodes(Set<NodeRef> nodeRefsToUnselect) {
        Iterator<NodeRef> selectedNode = getSelected().iterator();
        while (selectedNode.hasNext()) {
            NodeRef selectedNodeRef = selectedNode.next();
            if (nodeRefsToUnselect.contains(selectedNodeRef))
                selectedNode.remove();
        }
    }

   public void setNavigator(NavigationBean navigator) {
      this.navigator = navigator;
        currentNodeId = this.navigator.getCurrentNodeId();
        selection = "";
   }

   public NavigationBean getNavigator() {
      return navigator;
   }

   public void setBrowseBean(BrowseBean browseBean) {
      this.browseBean = browseBean;
   }

   public BrowseBean getBrowseBean() {
      return browseBean;
   }
}

savic_prvoslav
Champ on-the-rise
Champ on-the-rise
As far as I can see this is not ajax multiselect, so it is not good solution.

My solution works a bit different :

on selecting ids are writen to hidden field and on submit this hiddend field value is send to backend .

When you click delete, cut, copy… action works like this:
   delete checks for selected nodes and deletes them.

Ofcourse our alfresco is higly modified so we have actions on selected nodes.