[ DWR Website | Web Application Index ]

Ajax Search Demo

This demo allows you to filter the data in a table.

Search:

Name Age Address

Search Demo

On each change to the filter field we either call the server function People.getMatchingFromLargeCrowd() to find matches, or, if we have already found a set of matches, we filter that set if this makes sense.

The server code simply searches the data using a RegEx.

public List<Person> getMatchingFromLargeCrowd(String filter)
{
List<Person> reply = new ArrayList<Person>();
Pattern regex = Pattern.compile(filter, Pattern.CASE_INSENSITIVE);
for (Person person : largeCrowd.values())
{
if (regex.matcher(person.getName()).find())
{
reply.add(person);
}
}
return reply;
}

Found rows are added to the page using dwr.util.addRows:

dwr.util.addRows("peoplebody", filtered, [
function(person) { return person.name.replace(pattern, "$1"); },
function(person) { return "$" + person.age; },
function(person) { return person.address; }
], { escapeHtml:false });

We use person.name.replace to highlight the matches.

HTML source:

<p>Search: <input id="filter" onkeyup="filterChanged();"/></p>
<table border="1" class="rowed grey">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Address</th>
</tr>
</thead>
<tbody id="peoplebody">
</tbody>
</table>

Javascript source:

function init() {
  Tabs.init('tabList', 'tabContents');
  dwr.util.setValue("filter", "");
  addSingleRow("peoplebody", "Please enter a search filter");
}

var peopleCache = [ ];
var lastFilter = "";

function fillTable(people) {
  people = people.reply;
  var filter = dwr.util.getValue("filter");
  var pattern = new RegExp("(" + filter + ")", "i");
  var filtered = [];
  for (i = 0; i < people.length; i++) {
    if (pattern.test(people[i].name)) {
      filtered.push(people[i]);
    }
  }
  dwr.util.removeAllRows("peoplebody");
  if (filtered.length == 0) {
    addSingleRow("peoplebody", "No matches");
  }
  else {
    dwr.util.addRows("peoplebody", filtered, [
      function(person) { return person.name.replace(pattern, "<span class='highlight'>$1</span>"); },
      function(person) { return person.age; },
      function(person) { return person.address; }
    ], { escapeHtml:false });
  }
  peopleCache = people;
}

function filterChanged() {
  var filter = dwr.util.getValue("filter");
  if (filter.length == 0) {
    dwr.util.removeAllRows("peoplebody");
    addSingleRow("peoplebody", "Please enter a search filter");
  }
  else {
    if (filter.charAt(0) == lastFilter.charAt(0)) {
        var people = {};
        people.reply = peopleCache;        
          fillTable(reply);
    }
    else {
         $.post("../../../dwr/jsonp/People/getMatchingFromLargeCrowd/" + filter.charAt(0), { },
         fillTable, "json");
    }
  }
  lastFilter = filter;
}

function addSingleRow(id, message) {
  dwr.util.addRows(id, [1], [
    function(data) { return message; }
  ], {
    cellCreator:function() {
      var td = document.createElement("td");
      td.setAttribute("colspan", 3);
      return td;
    }
  });
}

web.xml

Note: In order to enable JSON/JSONP you must add the following init-param to your DWR servlet definition in your web.xml (This is a snippet and is not a complete web.xml).


...
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<description>Direct Web Remoter Servlet</description>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>jsonpEnabled</param-name>
<param-value>true</param-value>
</init-param>
...

dwr.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr/dwr20.dtd">

<dwr>
<allow>
<create creator="new" javascript="People" scope="script">
<param name="class" value="org.getahead.dwrdemo.people.People"/>
</create>
<convert match="org.getahead.dwrdemo.people.Person" converter="bean"/>
</allow>
</dwr>