Live Search in JSF

Suppose we have list of things, or a table of things, and a search box. The list should update based on what the user types. Additionally, the search should be live, in that the table updates as the user is typing; they are not required to hit enter, click a button, or otherwise take some action.

For the first attempt at this, let's add a valueChangeListener to your inputText component.

<ice:inputText
  value="#{aBean.searchFilter}"
  valueChangeListener=#{aHandler.search}/>

The problem is that this is not triggered until the form submits. You're going to need to add some Javascript to make this happen. For the next attempt, let's hook some Javascript into the component's keyup event,

<ice:inputText
  value="#{aBean.searchFilter}"
  onkeyup="doSubmit(this)"/>

 and,

function doSubmit(element) {
  iceSubmitPartial(
    document.getElementById("form"),
    element,
    MouseEvent.CLICK
  );
  setFocus(element);
}

Note that I'm using Icefaces, and making use of their utility Javascript function icePartialSubmit() to do a "partial submit". In a nutshell, this submits only this element and ignores the rest of the form. The call to setFocus() avoids losing focus in the input after the submission (another Icefaces utility).

This solution works fine, as long as the user is a slow typer. To understand what's wrong, suppose the user (quickly) types "java".

  1. user types "j"
  2. keyup occurs for "j"
  3. form is submitted
  4. bean is updated with value "j"
  5. user types "a"
  6. response is return from #3
  7. input is updated with value from backing bean: "j"

The response overwrites the "a" that the user just typed. What we want to do is add a delay in the form submission. If the keyup occurs, queue a form submission. If another keyup occurs, unqueue the first form submission and queue another, etc. It's set/cancelTimeout() to the rescure for this,

function doSubmit(element) {
        iceSubmitPartial(
            document.getElementById("form"),
            element,
            MouseEvent.CLICK
        );
        submitTimeout = null;
        setFocus(element);
}

function submitNow(element) {
    if (submitTimeout != null) {
        clearTimeout(submitTimeout);
    }
    submitTimeout = setTimeout(function(){doSubmit(element)}, 1000);
} 

The component binds keyup to submitNow(),

<ice:inputText
  value="#{aBean.searchFilter}"
  valueChangeListener=#{aHandler.search}
  onkeyup="submitNow(this)"/>

We use a delay of 1s. This still isn't perfect, because there's still a chance that the user will type something between a form submission and response. It is however much less likely considering average typing patterns.


Comments:

Alain commented on my previous post that the solution there was problematic as it allowed access to arbitrary view which may depend on objects being set up in other views

Posted by links of london on December 13, 2009 at 01:58 PM PST #

jean style jean style jeans stylejeans style mens jean style mens jean style skinny jean style skinny jean style blue jeans style blue jeans style seven jeans style seven jeans style new jean style new jean style latest jean style latest jean style jeans styles jeans styles boy style jeans boy style jeans men jean style men jean style jean style 

Posted by jean style on December 17, 2009 at 02:16 PM PST #

The select items have object values. http://www.watchgy.com/ All is good. When I submit the form, I see "Validation Error: Value is not valid". My first reaction was that I didn't have any validation on the page, so how could a value be not valid? http://www.watchgy.com/tag-heuer-c-24.html
http://www.watchgy.com/rolex-submariner-c-8.html

Posted by rolex replica on December 29, 2009 at 12:06 AM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

jtb

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today