ICEfaces 数据表内的多个 selectInputText 小部件行为不稳定

发布于 2024-09-09 00:27:23 字数 3489 浏览 0 评论 0原文

我在数据表中有多个 selectInputText 控件,如下所示:

<ice:dataTable id="attributesList" value="#{myForm.myAttributes}" var="entry" cellpadding="0" rows="9999" columnClasses="myColumn,myColumn">
  <ice:column>
    <!-- auto-complete -->
    <ice:panelGroup>
      <ice:selectInputText rows="15" width="120" maxlength="255" value="#{entry.attribute.stringValue}" valueChangeListener="#{myFieldAutocomplete.updateList}" immediate="true">
        <f:selectItems value="#{myFieldAutocomplete.list}" />
        <f:attribute name="fieldName" value="#{entry.name}" />
      </ice:selectInputText>
    </ice:panelGroup>
  </ice:column>
</ice:dataTable>

我的支持 bean 代码是这样的:

public class myFieldAutocomplete {

   // default value, empty string
   private String currentFieldValue = "";

   // list of possible matches.
   private List<SelectItem> matchesSIList = new ArrayList<SelectItem>();

   public void updateList(ValueChangeEvent event) {
      currentFieldValue = "";
      // get a new list of matches.
      setMatches(event);

      if (event.getComponent() instanceof SelectInputText) {
         SelectInputText autoComplete = (SelectInputText) event.getComponent();
         if (autoComplete.getSelectedItem() != null) {
            currentFieldValue = (String) autoComplete.getSelectedItem().getValue();
         }
         else {
            String tempValue = getMatch(autoComplete.getValue().toString());
            if(tempValue != null) {
               currentFieldValue = tempValue;
            }
         }
      }
   }

   public String getCurrentFieldValue() {
      return currentFieldValue;
   }

   public List<SelectItem> getList() {
       return matchesSIList;
   }

   private String getMatch(String value) {
      String result = null;
      if (matchesSIList != null) {
          String str;
          Iterator<SelectItem> itr = matchesSIList.iterator();
          while (itr.hasNext()) {
              SelectItem si = (SelectItem) itr.next();
              str = (String) si.getValue();
              if (str.startsWith(value)) {
                  result = str;
                  break;
              }
          }
      }
      return result;
   }

   public void setMatches(ValueChangeEvent event) {
      List<String> newMatchesStrList = new ArrayList<String>();
      if (event.getComponent() instanceof SelectInputText) {
         SelectInputText autoComplete = (SelectInputText) event.getComponent();
         myClassDAO myDao = (myClassDAO) Context.getInstance().getBean(myClassDAO.class);
         String fieldName = (String) autoComplete.getAttributes().get("fieldName");
         newMatchesStrList = myDao.findTemplateFieldValues((String)autoComplete.getValue(), fieldName);
      }
      // assign new matchList
      if (this.matchesSIList != null) {
          this.matchesSIList.clear();
      }
      Iterator<String> itr = newMatchesStrList.iterator();
      while(itr.hasNext()) {
         String str = (String) itr.next();
         matchesSIList.add(new SelectItem(str, str));
      }
   }
}

该 bean 在请求范围内(尽管我也尝试过会话范围)。我正在使用 ICEfaces 社区版 1.8.2。

问题是,这些自动完成控件是根据数据表中每个条目的某些属性动态创建的。因此,您可以在同一个 panelGroup 中拥有 2 个或更多此类自动完成控件。在这种情况下,当您开始在第一个控件中输入某些内容时,它似乎会触发所有同级自动完成控件的事件,并最终按顺序返回最后一个控件的列表。 一般来说,我注意到由于所有自动完成控件同时触发事件而导致的不稳定行为,并且值/列表变得混乱。

我做错了什么?

提前致谢!

I have multiple selectInputText controls inside a datatable, something like this:

<ice:dataTable id="attributesList" value="#{myForm.myAttributes}" var="entry" cellpadding="0" rows="9999" columnClasses="myColumn,myColumn">
  <ice:column>
    <!-- auto-complete -->
    <ice:panelGroup>
      <ice:selectInputText rows="15" width="120" maxlength="255" value="#{entry.attribute.stringValue}" valueChangeListener="#{myFieldAutocomplete.updateList}" immediate="true">
        <f:selectItems value="#{myFieldAutocomplete.list}" />
        <f:attribute name="fieldName" value="#{entry.name}" />
      </ice:selectInputText>
    </ice:panelGroup>
  </ice:column>
</ice:dataTable>

My backing bean code is this:

public class myFieldAutocomplete {

   // default value, empty string
   private String currentFieldValue = "";

   // list of possible matches.
   private List<SelectItem> matchesSIList = new ArrayList<SelectItem>();

   public void updateList(ValueChangeEvent event) {
      currentFieldValue = "";
      // get a new list of matches.
      setMatches(event);

      if (event.getComponent() instanceof SelectInputText) {
         SelectInputText autoComplete = (SelectInputText) event.getComponent();
         if (autoComplete.getSelectedItem() != null) {
            currentFieldValue = (String) autoComplete.getSelectedItem().getValue();
         }
         else {
            String tempValue = getMatch(autoComplete.getValue().toString());
            if(tempValue != null) {
               currentFieldValue = tempValue;
            }
         }
      }
   }

   public String getCurrentFieldValue() {
      return currentFieldValue;
   }

   public List<SelectItem> getList() {
       return matchesSIList;
   }

   private String getMatch(String value) {
      String result = null;
      if (matchesSIList != null) {
          String str;
          Iterator<SelectItem> itr = matchesSIList.iterator();
          while (itr.hasNext()) {
              SelectItem si = (SelectItem) itr.next();
              str = (String) si.getValue();
              if (str.startsWith(value)) {
                  result = str;
                  break;
              }
          }
      }
      return result;
   }

   public void setMatches(ValueChangeEvent event) {
      List<String> newMatchesStrList = new ArrayList<String>();
      if (event.getComponent() instanceof SelectInputText) {
         SelectInputText autoComplete = (SelectInputText) event.getComponent();
         myClassDAO myDao = (myClassDAO) Context.getInstance().getBean(myClassDAO.class);
         String fieldName = (String) autoComplete.getAttributes().get("fieldName");
         newMatchesStrList = myDao.findTemplateFieldValues((String)autoComplete.getValue(), fieldName);
      }
      // assign new matchList
      if (this.matchesSIList != null) {
          this.matchesSIList.clear();
      }
      Iterator<String> itr = newMatchesStrList.iterator();
      while(itr.hasNext()) {
         String str = (String) itr.next();
         matchesSIList.add(new SelectItem(str, str));
      }
   }
}

The bean is in request scope (although I also tried with session scope). I am using ICEfaces community edition 1.8.2.

The problem is, these auto-complete controls are created dynamically based on certain attributes of each entry in the datatable. So, you can have, for example 2 or more such auto-complete controls in the same panelGroup. When this is the case, when you start typing something the first control, it seems to be triggering the event for all sibling auto-complete controls, and in the end returns the list for the last in order.
In general, I noticed erratic behavior caused by the fact that the event is triggered for all auto-complete controls at once, and values/lists get confused.

What am I doing wrong?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文