通过JSF 2实现可重用的Ajax化组件(1)(6)
分享于 点击 10696 次 点评:134
清单6显示了监听程序的最终实现:
清单6.监听程序
- package com.corejsf;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import javax.enterprise.context.SessionScoped;
- import javax.faces.component.UIInput;
- import javax.faces.component.UISelectItems;
- import javax.faces.component.UISelectOne;
- import javax.faces.context.FacesContext;
- import javax.faces.event.ValueChangeEvent;
- import javax.inject.Named;
- @Named
- @SessionScoped
- public class AutocompleteListener implements Serializable {
- private static String COMPLETION_ITEMS_ATTR = "corejsf.completionItems";
- public void valueChanged(ValueChangeEvent e) {
- UIInput input = (UIInput)e.getSource();
- UISelectOne listbox = (UISelectOne)input.findComponent("listbox");
- if (listbox != null) {
- UISelectItems items = (UISelectItems)listbox.getChildren().get(0);
- Map<String, Object> attrs = listbox.getAttributes();
- List<String> newItems = getNewItems((String)input.getValue(),
- getCompletionItems(listbox, items, attrs));
- items.setValue(newItems.toArray());
- setListboxStyle(newItems.size(), attrs);
- }
- }
- public void completionItemSelected(ValueChangeEvent e) {
- UISelectOne listbox = (UISelectOne)e.getSource();
- UIInput input = (UIInput)listbox.findComponent("input");
- if(input != null) {
- input.setValue(listbox.getValue());
- }
- Map<String, Object> attrs = listbox.getAttributes();
- attrs.put("style", "display: none");
- }
- private List<String> getNewItems(String inputValue, String[] completionItems) {
- List<String> newnewItems = new ArrayList<String>();
- for (String item : completionItems) {
- String s = item.substring(0, inputValue.length());
- if (s.equalsIgnoreCase(inputValue))
- newItems.add(item);
- }
- return newItems;
- }
- private void setListboxStyle(int rows, Map<String, Object> attrs) {
- if (rows > 0) {
- Map<String, String> reqParams = FacesContext.getCurrentInstance()
- .getExternalContext().getRequestParameterMap();
- attrs.put("style", "display: inline; position: absolute; left: "
- + reqParams.get("x") + "px;" + " top: " + reqParams.get("y") + "px");
- attrs.put("size", rows == 1 ? 2 : rows);
- }
- else
- attrs.put("style", "display: none;");
- }
- private String[] getCompletionItems(UISelectOne listbox,
- UISelectItems items, Map<String, Object> attrs) {
- Strings] completionItems = (String[])attrs.get(COMPLETION_ITEMS_ATTR);
- if (completionItems == null) {
- completionItems = (String[])items.getValue();
- attrs.put(COMPLETION_ITEMS_ATTR, completionItems);
- }
- return completionItems;
- }
- }
JSF在Ajax调用期间调用监听程序的valueChanged()方法来响应文本输入中的keyup事件。该方法会创建一组新的完成项目,然后将列表框的项目设置为这个新的项目集。该方法还会设置列表框的样式属性,以确定Ajax调用返回时是否显示列表框。
清单6中的setListboxStyle()方法将使用x和y请求我在发起清单5中的Ajax调用时指定的参数值。
JSF会在Ajax调用期间调用监听程序的其他公共方法completionItemSelected(),以响应列表框中的选择事件。该方法会将列表框的值复制到文本输入中,并隐藏列表框。
请注意,valueChanged()方法还会将原始完成项目存储在列表框的某个属性中。由于每个autoComplete组件都维护自己的完成项目列表,因此多个autoComplete组件可以在相同页面中和谐共存,而不会影响彼此的完成项目。
相关文章
- 暂无相关文章
用户点评