6 Replies Latest reply on Mar 6, 2015 4:02 PM by paulineg

    rich:picklist execute does not work when list is empty

    paulineg

      I have a rich:picklist with a searchbox. The picklist is executed and the values saved when the searchbox gets focus. This works fine, however if the last item is removed  from the selected list (making the selected list empty) and then the searchbox gets focus the setter is NOT called for the picklist values and the last item reappears in the list. Is this a richfaces bug? How can I get the updated list even when the list is empty.

        • 1. Re: rich:picklist execute does not work when list is empty
          michpetrov

          Without seeing any code it's hard to tell what might be wrong, can you share some? Also what version of RichFaces are you using?

          • 2. Re: Re: rich:picklist execute does not work when list is empty
            paulineg
            <h:outputText value="#{msg['label.button.Search']}  "/>
            <h:inputText id="searchStr" value="#{Bean.searchString}">
              <a4j:ajax event="keyup" render="conList" />
            <a4j:ajax event="focus" oncomplete="saveList()" />
            </h:inputText>
            <a4j:jsFunction name="saveList" execute="conList, searchStr" />
            
            <rich:pickList id="conList"
                 value="#{Bean.selectedConnections}"
                sourceCaption="#{msg['label.text.Report.AvailableConnections']}"
                 targetCaption="#{msg['label.text.Report.SelectedConnections']}"
                listWidth="400px" maxListHeight="200px" minListHeight="200px" orderable="false">
                      <f:selectItems value="#{Bean.filteredList}" var="item" itemValue="#{item}"/>
            </rich:pickList>
            

             

            I am using Richfaces 4.5.2-Final

            • 3. Re: rich:picklist execute does not work when list is empty
              michpetrov

              That works for me. Select a value, focus, put the value back, focus again, list is empty. I don't see how the value could reappear in the list if you're not rendering it. I also don't see the purpose of the inputText, does the "searchString" affect the "filteredList"? If yes then the problem is probably there.

              • 4. Re: Re: rich:picklist execute does not work when list is empty
                paulineg
                /**
                     *
                     * @return List<Long>
                     */
                    public List<String> getSelectedConnections() {
                        return m_selectedConnections;
                    }
                
                    /**
                     *
                     * @param selectedConnections
                     */
                    public void setSelectedConnections(List<String> selectedConnections) {
                        this.m_selectedConnections = selectedConnections;
                    }
                

                 

                I have a getter and setter in my Bean. So I select a value, focus (setter above gets called). I remove the value, focus (setter does not get called), now I start typing in the searchbox and the value reappears.  When the setter gets called everything works fine.

                 

                Code for the filtering

                 

                 public List<String> getFilteredList() {
                        if (m_filteredList == null) {
                            m_filteredList = new ArrayList<String>();
                        }
                        
                        List<String> sourceList = m_availableConnections;
                        List<String> targetList = m_selectedConnections;
                        
                
                        if ((m_searchString != null) && (!m_searchString.isEmpty())) {
                            List<String> filteredList = new ArrayList<String>();
                           
                            for (String s : sourceList) {
                                if (s.toUpperCase().contains(m_searchString.toUpperCase()) && !targetList.contains(s)) {
                                    filteredList.add(s);
                                }
                            }
                
                            // we need to add the selected items so they would be rendered
                            // target list needs to be a subset of the source list
                            filteredList.addAll(targetList);
                            
                            m_filteredList.clear();
                            for (String conName : filteredList) {
                                m_filteredList.add(conName);
                            }
                            
                            return m_filteredList;
                        } else {
                            m_filteredList.clear();
                            m_filteredList.addAll(sourceList);
                            return m_filteredList;
                        }
                    }
                
                • 5. Re: rich:picklist execute does not work when list is empty
                  michpetrov

                  Business methods do not belong into setters and getters, they will often be called multiple times during the request and you don't want the business logic to execute more than once. Call the filtering via the listener attribute of a4j:ajax instead.

                  • 6. Re: Re: rich:picklist execute does not work when list is empty
                    paulineg

                    Ok, I updated my code to call the filter method onkeyup instead of in the getter. But I still have the same problem. The focus event does not call the setSelectedConnections method when all items have been removed from the picklist. (I need it to set an empty list so that my filter method have the correct values for the search)

                     

                    <h:inputText id="searchStr" value="#{Bean.searchString}">
                        <a4j:ajax event="keyup" listener="#{Bean.filterConnections}" render="conList" >
                             <a4j:attachQueue name="searchQueue"/> 
                        </a4j:ajax>
                        <a4j:ajax event="focus" oncomplete="saveList()" />
                    </h:inputText>
                    <a4j:jsFunction name="saveList" execute="conList, searchStr" />
                    

                     

                    Note that I did try adding

                     

                    <a4j:ajax event="additems" execute="@this"/>

                    <a4j:ajax event="removeitems" execute="@this"/>

                     

                    to the rich:picklist but this was worse than what I currently have. The list didn't get saved correctly when adding and removing items.