title: Primefaces p:picklist get selected Items in target list
body: <p>I'd like to get the selected elements in my target list of a p:picklist</p>
  
  <p>1: the ajax event="select" gets me only the last selected element, but i need to get all selected elements.</p>
  
  <p>My picklist:</p>
  
  <pre><code>&lt;p:pickList
                  id="xAttributesPicklist_#{!templateController.model.template.transposed}"
                  value="#{templateController.model.listAttributesX}"
                  var="attributesX" itemValue="#{attributesX}"
                  itemLabel="#{attributesX.getName(localeBean.selectedLocale)}"
                  showTargetControls="true" showCheckbox="true"
                  converter="attributePicklistConverter"
                  styleClass="attributesPicklist"
                  rendered="#{!templateController.model.template.transposed}"&gt;
  
                  &lt;f:facet name="sourceCaption"&gt;#{msg.pickListAvailableAttributesX}&lt;/f:facet&gt;
                  &lt;f:facet name="targetCaption"&gt;#{msg.pickListAssignedAttributesX}&lt;/f:facet&gt;
  
                  &lt;p:ajax event="select"
                      listener="#{templateController.onPickListXSelect}"
                      update="@([id$=radioAttributeXOrder_#{!templateController.model.template.transposed}])" /&gt;
                  &lt;p:ajax event="unselect"
                      listener="#{templateController.onPickListXUnSelect}" /&gt;
  
                  &lt;p:ajax event="reorder"
                      listener="#{templateController.onPickListXReorder}"
                      update="@([id$=radioAttributeXOrder_#{!templateController.model.template.transposed}])"
                      oncomplete="setFromDirty();" /&gt;
  
                  &lt;p:ajax event="transfer" oncomplete="setFromDirty();" update="@([id$=panelGridReportButtons])" /&gt;
  
  
                  &lt;p:column styleClass="picklistColumnBase"&gt;
                      &lt;h:outputText
                          value="#{attributesX.getName(localeBean.selectedLocale)}" /&gt;
                  &lt;/p:column&gt;
                  &lt;p:column styleClass="picklistColumnDetail"&gt;
                      &lt;h:outputText
                          styleClass="#{attributesX.ascending ? 'ui-icon ui-icon-circle-arrow-n' : 'ui-icon ui-icon-circle-arrow-s'}" /&gt;
                  &lt;/p:column&gt;
              &lt;/p:pickList&gt;
  </code></pre>
  
  <p>The bean method to handle the select event:</p>
  
  <pre><code>    public void onPickListXSelect(SelectEvent event) {
      this.model.setSelectedAttributeX((TAttributeX) event.getObject());
      this.model.setAttributesXAscending(this.model.getSelectedAttributeX().isAscending());
  }
  </code></pre>
  
  <p>I also have a p:selectOneRadio in my form, which (on change) should modify all selected elements of my targetList in the picklist.</p>
  
  <pre><code>&lt;p:selectOneRadio
                  id="radioAttributeXOrder_#{!templateController.model.template.transposed}"
                  value="#{templateController.model.attributesXAscending}"
                  layout="grid" columns="1" styleClass="selectRadio"
                  rendered="#{!templateController.model.template.transposed}"
                  onchange="setFromDirty();"&gt;
                  &lt;f:selectItem itemLabel="#{msg.btnRadioAscending}" itemValue="true" /&gt;
                  &lt;f:selectItem itemLabel="#{msg.btnRadioDescending}"
                      itemValue="false" /&gt;
  
                  &lt;p:ajax event="valueChange"
                      listener="#{templateController.updateAttributesXOrder()}"
                      update="@([id$=xAttributesPicklist_#{!templateController.model.template.transposed}])" /&gt;
              &lt;/p:selectOneRadio&gt;
  </code></pre>
  
  <p>My current bean method to handle the changeevent in the p:selectOneRadio:</p>
  
  <pre><code>    public void updateAttributesXOrder() {
      if (this.model.getSelectedAttributeX() != null) {
          this.model.getSelectedAttributeX().setAscending(this.model.isAttributesXAscending());
      }
  }
  </code></pre>
  
  <p>But it acutally should look something like this:</p>
  
  <pre><code>    public void updateAttributesXOrder() {
      if (this.model.getSelectedAttributeXs() != null) {
          for (AttributeX attx : this.model.getSelectedAttributeXs()) {
              attx.setAscending(this.model.isAttributesXAscending());
          }
      }
  }
  </code></pre>
  
  <p>What I need is a way to keep track of <strong>ALL</strong> selected elements in my targetList, not only the last one (as I get from the select event).</p>
  
  <p>Problem with filling a list of selected elements (with adding the current selected element in a select event) is, that I never get a unselect event when the user changes the multiselection into a single element selection.</p>
  
  <p><strong>Update based on reply of Kukeltje:</strong></p>
  
  <p>added a <code>&lt;p:ajax onstart&gt;</code> to my selectOneRadio:</p>
  
  <pre><code>&lt;p:selectOneRadio
                  id="radioAttributeXOrder_#{!templateController.model.template.transposed}"
                  value="#{templateController.model.attributesXAscending}"
                  layout="grid" columns="1" styleClass="selectRadio"
                  rendered="#{!templateController.model.template.transposed}"
                  onchange="setFromDirty();"&gt;
                  &lt;f:selectItem itemLabel="#{msg.btnRadioAscending}" itemValue="true" /&gt;
                  &lt;f:selectItem itemLabel="#{msg.btnRadioDescending}"
                      itemValue="false" /&gt;
  
                  &lt;p:ajax
                      onstart="getSelectedElementsInPicklist('tempalteForm:tabViewProperties:xAttributesPicklist_#{!templateController.model.template.transposed}')"
                      event="valueChange"
                      listener="#{templateController.updateAttributesXOrder()}"
                      update="@([id$=xAttributesPicklist_#{!templateController.model.template.transposed}])" /&gt;
              &lt;/p:selectOneRadio&gt;
  </code></pre>
  
  <p>with the corresponding JS to "find" the selected IDs:</p>
  
  <pre><code>        function getSelectedElementsInPicklist(table) {
          var parent = document.getElementById(table)
          var targetListWrapper = parent.childNodes[2];
          var targetListElements = targetListWrapper.childNodes[1]; // ul
  
          var items = targetListElements.getElementsByTagName("li");
  
          var ret_obj = new Array();
  
          for (var i = 0; (i &amp;lt; items.length); ++i) 
          {
              var pickListItem = items[i];
              if (pickListItem.className.indexOf('ui-state-highlight') != -1) 
              {
                  ret_obj.push(pickListItem.getAttribute('data-item-value'));
              }
          }
  
          var resultString = "";
  
          for (var j = 0; (j &amp;lt; ret_obj.length); ++j)
          {
              resultString = resultString + ret_obj[j] + ", ";
          }
  
          resultString = resultString.substring(0, resultString.length - 2);
  
          passToJSFManagedBean ([{name : 'selected_picklist_items', value : resultString}]);
  
      }
  </code></pre>
  
  <p>I am struggling on how to work with this result the "right way". At the moment i pass the resultString (which represents the selected IDs) to my request map. and calling remotecommand</p>
  
  <pre><code>            &lt;p:remoteCommand name="passToJSFManagedBean"
              id="passToJSFManagedBeanCmd"
              action="#{templateController.getParamsFromJS()}" process="@this"&gt;&lt;/p:remoteCommand&gt;
  </code></pre>
  
  <p>In my Controller I read this on out and get the IDs:</p>
  
  <pre><code>    public void getParamsFromJS() {
      String selectedPicklistItems = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
              .get("selected_picklist_items");
  
      String[] picklistIds = selectedPicklistItems.split(", ");
  
      List&lt;Long&gt; selectedPicklistIds = new ArrayList&lt;Long&gt;();
  
      for (String s : picklistIds) {
          selectedPicklistIds.add(Long.valueOf(s));
      }
  
      this.setSelectedItemIdsInPicklist(selectedPicklistIds);
  }
  </code></pre>
  
  <p>My problem now is that the listener-method of the ajax event "valueChange" of my selectOneRadio is called <strong>before</strong> the getParamsFromJS() Methode is invoked. So apparently I'm doing something wrong :-)</p>
  
  <p>Help or any suggestions would be great</p>
  
  <p>Thank you.</p>