JSF2搜索框

时间:2011-09-25 07:59:22

标签: java-ee jsf-2

我在javaee6和jsf2中开发了一个小应用程序。我想要一个没有按钮的搜索字段(只需键入并按Enter键并给出结果)。 我在bean中有一个搜索方法:

public Book searchByTitle(String title) {
    this.book = bookFacade.searchByTitle(title);
    return book;
}

我想通过jsf页面调用此方法(带参数?可能吗?),所以我尝试这样做:

    <h:form>
        <h:inputText id="search" value="#{bookBean.searchString}"></h:inputText>
        <h:commandButton value="Search by title" action="#{bookBean.searchByTitle}">
            <f:ajax execute="search" render="output"></f:ajax>
        </h:commandButton>
        <h2><h:outputText id="output" value="#{bookBean.book.title}"></h:outputText>
        </h2>
    </h:form>

但这不起作用。 在jsf2 xhtml页面中执行搜索字段的正确方法是什么?

编辑:我尝试使用/不带参数调用searchByTitle函数。

提前致谢!

2 个答案:

答案 0 :(得分:6)

第一步,如果您使用的是Java EE 6兼容容器(如GlassFish V3,Resin 4,JBoss AS 6或7等),并且在WEB-INF中放置了类似commons-el.jar的内容,< strong>删除它。这不是必需的,只会造成伤害。

  

我想要一个没有按钮的搜索字段(只需键入并按Enter键并给出结果)

在这种情况下,您也不需要命令按钮,但可以使用以下内容:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
>
    <h:head/>

    <h:body>        

        <h:form>
            <h:inputText id="search" value="#{bookBean.searchString}" 
                onkeypress="if (event.keyCode == 13) {onchange(event); return false;}"
                onchange="return event.keyCode !== undefined" 
            >
                <f:ajax listener="#{bookBean.updateBook}" render="output" />
            </h:inputText>

            <h2>
                <h:outputText id="output" value="#{bookBean.book}"/>
            </h2>
        </h:form>

    </h:body>
</html>

bookBean定义为:

@ViewScoped
@ManagedBean
public class BookBean {

    private Map<String, String> exampleData = new HashMap<String, String>() {{ 
        put("dune", "The Dune Book"); 
        put("lotr", "The Lord of the Rings Book");
    }};

    private String searchString; 
    private String book;

    public void updateBook(AjaxBehaviorEvent event) {
        book = exampleData.get(searchString);
    }

    public String getSearchString() {
        return searchString;
    }

    public void setSearchString(String searchString) {
        this.searchString = searchString;
    }

    public String getBook() {
        return book;
    }

}

在Facelet中,请注意h:head元素的重要性。没有它,JSF不知道在响应中为AJAX支持插入所需的脚本。

在该示例中,只要用户按Enter键,就会在将onchange客户端行为添加到所谓的f:ajax时生成JSF生成的默认EditableValueHolder方法。 listener属性导致在AJAX事件上调用方法。由于searchString已绑定到辅助bean的属性,因此您不必将其作为参数提供给侦听器方法。

此方法的一个小缺点是,当您更改搜索字段中的值并只需在其外部单击时,也会调用AJAX调用。

<强>更新

onchange添加h:inputText处理程序修复了上述问题。这由JSF自动链接来自客户端行为的AJAX代码。如果它返回false,则链被中止,因此不会发生AJAX调用。

如果处理程序由真实更改事件触发,则处理程序onchange="return event.keyCode !== undefined"将返回false;然后,事件对象将不具有keyCode属性。

答案 1 :(得分:1)

将以下代码用于jsf页面:

<h:form>
    <h:inputText id="search" value="#{bookBean.searchString}"></h:inputText>
    <h:commandButton value="Search by title" action="#{bookBean.searchByTitle(bookBean.searchString)}">
        <f:ajax execute="search" render="output"></f:ajax>
    </h:commandButton>
    <h2><h:outputText id="output" value="#{bookBean.book.title}"></h:outputText>
    </h2>
</h:form>

你的java代码:

// note the return type is String. return type of methods which are to be called from actions of commandlinks or commandbuttons should be string
public String searchByTitle(String title)
{
    this.book = bookFacade.searchByTitle(title);
    return null;
}

编辑:

首先,就涉及从jsf页面传递的参数而言,只有在想要将一个bean的属性传递给另一个bean时才应该使用它。在您的情况下,它不是必需的,因为您正在设置同一个bean的属性(searchString),并将其传递给同一个bean。

您的第二个问题:您希望搜索无需搜索按钮即可:您可以通过向valueChangeListener添加h:inputText来执行此操作。并将event的{​​{1}}属性设置为f:ajax

blur

还要将bookChangeListener方法定义为bookBean java代码:

<h:form>
    <h:inputText id="search" value="#{bookBean.searchString}" valueChangeListener="#{bookBean.searchStringChanged}">
        <f:ajax execute="search" render="output" event="blur" />
    </h:inputText>
    <h2><h:outputText id="output" value="#{bookBean.book.title}" />
    </h2>
</h:form>