2012-01-26 3 views
1

Я пытаюсь сделать автозаполнение при вводе символов во льду: selectInputText Проблема, с которой я сталкиваюсь, - это когда я печатаю символы, они приносят даже имена, которые не совпадают с введенными мной символами. См. Приведенный ниже снимок экрана для справки.Autocomplete непревзойденные результаты

a http://s7.postimage.org/46jk4tka3/autocomplete.png

В идеале автозаполнение должно отображать только первую строку из результата, однако он отображает строки, которые не совпадающие мои набранные символы.

Только Abell Maryland 20606 должен отображать.

Это код, который используется для сравнения, как я могу изменить это в соответствии с моим требованием, которое отображает только те результаты, которые соответствуют тому, что я набираю.

public int compare(Object o1, Object o2) { 
     if (o1 instanceof SelectItem) { 
      s1 = ((SelectItem) o1).getLabel(); 
     } else { 
      s1 = o1.toString(); 
     } 

     if (o2 instanceof SelectItem) { 
      s2 = ((SelectItem) o2).getLabel(); 
     } else { 
      s2 = o2.toString(); 
     }    
     return s1.compareToIgnoreCase(s2); 
    } 
}; 

Я после этого урока из ICEfaces

http://wiki.icefaces.org/display/ICE/Auto-Complete

Update

Мой код в autocomplete.jspx

<ice:selectInputText rows="10" width="300" 
         listVar="emp" 
         valueChangeListener="#{mybean.updateList}" 
         listValue="#{mybean.list}"> 
         <f:facet name="selectInputText"> 
        <ice:panelGrid columns="3" columnClasses="empNameCol"> 
         <ice:outputText value="#{emp.empName}"/>       
        </ice:panelGrid> 

метод updateList

public void updateList(ValueChangeEvent event) { 

    setMatches(event); 

    if (event.getComponent() instanceof SelectInputText) { 
     SelectInputText autoComplete = (SelectInputText)event.getComponent(); 
     if (autoComplete.getSelectedItem() != null) { 
      bean = (Bean)autoComplete.getSelectedItem().getValue(); 
     }    
     else { 
      Bean tempCity = getMatch(autoComplete.getValue().toString()); 
      if (tempCity != null) { 
       bean = tempCity; 
      } 
     } 
    } 
} 

Метод setMatches

private void setMatches(ValueChangeEvent event) { 

Object searchWord = event.getNewValue(); 
int maxMatches = ((SelectInputText)event.getComponent()).getRows(); 
List matchList = new ArrayList(maxMatches); 

try { 
    int insert = 
     Collections.binarySearch(dictionary, searchWord, AutoCompleteDictionary.LABEL_COMPARATOR);    
    if (insert < 0) { 
     insert = Math.abs(insert) - 1; 
    } 

    for (int i = 0; i < maxMatches; i++) {         
     if ((insert + i) >= dictionary.size() || i >= maxMatches) { 
      break; 
     } 
     matchList.add(dictionary.get(insert + i)); 
    } 
} catch (Throwable e) { 
    e.printStackTrace(); 
    logger.error("Erorr finding autocomplete matches" + e.getMessage()); 
}   
if (this.matchesList != null) { 
    this.matchesList.clear(); 
    this.matchesList = null; 
} 
this.matchesList = matchList; 

}

Update 2

Модифицированный метод setMatches

private void setMatches(ValueChangeEvent event) { 
     Object searchWord = event.getNewValue(); 
     int maxMatches = ((SelectInputText) event.getComponent()).getRows(); 
     List matchList = new ArrayList(maxMatches); 
     try { 
      for(int i = 0; i < dictionary.size(); i++) { 
       SelectItem s = (SelectItem)dictionary.get(i); 
       if(s.getLabel().startsWith(searchWord.toString())) { 
        matchList.add(s); 
        if(matchList.size() == maxMatches) 
         break; 
       } 
      } 
     } catch (Throwable e) { 
      e.printStackTrace(); 
      logger.error("Erorr finding autocomplete matches" + e.getMessage()); 
     }   
     if (this.matchesList != null) { 
      this.matchesList.clear(); 
      this.matchesList = null; 
     } 
     this.matchesList = matchList; 
     } 

ответ

1

Вы должны обновить список SelectItems. Вместо того, чтобы просто отбирать список, вам нужно отфильтровать список (или создать новый, который содержит только совпадения). В следующий раз, когда появится список автозаполнения, он снова оценит связанный список.

В учебнике ледовых поверхностей есть некоторые источники, прикрепленные (внизу). Взгляните на AutoCompleteBean. Метод updateList(ValueChangeEvent e) вызывает setMatches(e). В этом методе список присваивается новому.

// assign new matchList 
if (this.matchesList != null) { 
    this.matchesList.clear(); 
    this.matchesList = null; 
} 
this.matchesList = matchList; 

Это приводит к тому, что компонент ui отображает только элементы, которые соответствуют входу.

Подводя итог: ice:selectInputList всегда будет показывать элементы, содержащиеся в его списке, поэтому уменьшите элементы в списке, чтобы отображать только соответствующие.

С уважением

Update

private void setMatches(ValueChangeEvent event) { 
Object searchWord = event.getNewValue(); 
int maxMatches = ((SelectInputText)event.getComponent()).getRows(); 
List matchList = new ArrayList(maxMatches); 

try { 
    for(int i = 0; i < dictionary.size(); i++) { 
     SelectItem s = dictionary.get(i); 
     if(s.getLabel().startsWith(searchWord)) { 
      matchList.add(s); 
      if(matchList.size() == maxMatches) 
       break; 
     } 
    } 
} catch (Throwable e) { 
    e.printStackTrace(); 
    logger.error("Erorr finding autocomplete matches" + e.getMessage()); 
}   
if (this.matchesList != null) { 
    this.matchesList.clear(); 
    this.matchesList = null; 
} 
this.matchesList = matchList; 
} 

// note: not optimized, just to explain how to do. 

Update 2 (короткая версия)

/** 
* Fills the suggestionList with the given luceneResult. 
* 
* @param suggestionList     The list to fill. 
* @param luceneResult     The previously computed luceneResult. 
*/ 
private static void fillLookupSuggestionList(final List<SelectItem> suggestionList, 
    LuceneResult luceneResult) 
{ 
    suggestionList.clear(); 

    String searchQuery = luceneResult.getLuceneResultConfig().getSearchQuery(); 
    if (luceneResult.getResultSize() <= 0) 
    { 
     suggestionList.add(new SelectItem(null, BundleHelper.i18n(LuceneLookupController.BUNDLE, 
      LuceneLookupController.NO_ITEM_FOUND))); 
    } 
    else 
    { 
     List<LuceneResultEntry> results = luceneResult.getResult(); 
     for (LuceneResultEntry entry : results) 
     { 
      suggestionList.add(new SelectItem(entry.getMetaInfo(), 
       entry.getInfo().getDescription())); 
     } 
    } 
} 
+0

У меня есть сомнения в этом, я уже использую этот кусок кода в updatelist. '// присваиваем новый matchList if (this.matchesList! = null) { this.matchesList.clear(); this.matchesList = null; } this.matchesList = matchList; 'Тогда почему я не могу уменьшить элементы, содержащиеся в списке? Извините, что задал этот вопрос, поскольку я не понял вашу точку зрения. – user75ponic

+1

@Polappan Hi. Я также использую этот компонент. Каждый раз, когда пользователь вводит что-то, я начинаю поиск Lucene, который возвращает результаты. Каждый раз при запуске поиска я должен создать новый список SelectItems. Этот временный список присваивается члену bean-компонента, который привязан к компоненту. На данный момент мне трудно понять, как вы уменьшаете элемент своего списка. В приведенном выше коде показана только сортировка. Не могли бы вы предоставить некоторый код, показывающий, как сокращение (и повторное назначение) выполняется? –

+0

Спасибо за помощь. Я добавил свой код в качестве обновления к моему первоначальному сообщению выше. Мой код почти такой же, как и код учебника, за исключением источника данных. – user75ponic

Смежные вопросы