Search code examples
javaajaxjsfrichfaces

Block a4j:support call when the input value is empty


Here is my code:

<h:inputText size="22" 
    value="#{bean.searchString}"
    id="drugName">

    <a4j:support
        actionListener="#{bean.searchMedication}"
        ajaxSingle="true" reRender="contentListGrid"
        event="onkeyup" id="searchAjax" 
        requestDelay="200" 
        rendered="#{bean.searchString.length() > 0}">
    </a4j:support>
</h:inputText> 

I would like to prevent the a4j:support call whenever the input field is not filled out. I tried it by determining the input value length in the rendered attribute. However, it results in the following exception:

org.apache.jasper.JasperException: /pages/medication/MedicationList.jsp(147,9) The function length must be used with a prefix when a default namespace is not specified
    at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
    at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
    at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:148)
    at org.apache.jasper.compiler.Validator$ValidateVisitor$1FVVisitor.visit(Validator.java:1478)

What does this message mean?

The function length must be used with a prefix when a default namespace is not specified

Can't we invoke a method in EL?


Solution

  • As to the concrete exception, invoking non-property methods (i.e. non-getter/setter methods) is only supported since EL 2.2 which is part of Servlet 3.0 / JSP 2.2. You seem to be using old JSF 1.x and thus also old Servlet 2.5 / JSP 2.1. Basically you end up with an EL syntax error.

    Actually, you don't need EL 2.2 for this. Just use empty keyword instead.

    rendered="#{not empty bean.searchString}"
    

    However this approach won't work as well. The rendered attribute will be examined in the server side when the HTML code is to be generated and sent to the browser, not during the client side events as you seem to expect (rightclick page in browser, View Source, do you see any JSF code?). You need to use JavaScript to check the input value length in the onkeyup of the field or onsubmit of the Ajax call and return false accordingly.

    <h:inputText ... onkeyup="return (!!value)">
    

    or (not guaranteed that this works, I don't know off top of head what markup it generates)

    <h:inputText ...>
        <a4j:support ... onsubmit="return (!!value)" />
    </h:inputText>
    

    The first ! converts it to inversed boolean and the second ! re-inverses it. This way you end up with a fullworthy boolean return outcome depending on the presence of any value. If it's false, then the remaining onkeyup functions (such as you've specified with <a4j:support>) will be blocked.