After a quick Google search, I found a pretty good plugin that looked like it would do what I wanted. However, there was a pretty big difference in how the two plugins work. Ajax.Autocompleter must return an unordered list (
<ul>
), with each suggestion rendered inside its own list item (<li>
). Piece of cake.However, the jQuery Autocompleter expects a string, with each suggestion rendered on its own line. This threw me for a loop at first, since ColdFusion isn't always the best at dealing with whitespace. After a little thought, here's what I came up with.
index.cfm
<link rel="stylesheet" type="text/css" href="jquery.autocomplete.css" />
<script src="jquery-1.3.2.js"></script>
<script src="jquery.autocomplete.js"></script>
<script type="text/javascript">
$().ready(function() {
$('#search').autocomplete('UserService.cfc?method=autocomplete&_cf_nodebug=true', {
multiple: true,
formatItem: function(row) {
var user = JSON.parse(row.toString());
return user.name;
},
formatResult: function(row) {
var user = JSON.parse(row.toString());
return user.email;
}
});
$('#search').result(function(event, data, formatted) {
var user = JSON.parse(data.toString());
alert('You selected user '+user.id);
});
});
</script>
<input type="text" id="search" name="search" size="60" />
UserService.cfc
component {
remote void function autocomplete(required string q) {
// get the users
var users = searchUsers(arguments.q);
var result = [];
var i = "";
for (i=1; i <= arrayLen(users); i++) {
// build the user record
var user = {};
// maintain lowercase keys
user["id"] = users[i].id;
user["name"] = users[i].name & " (" & users[i].email & ")";
user["email"] = users[i].email;
// serialize the user record and append it to the result
arrayAppend(result, serializeJSON(user));
}
// convert the result from an array to a list, with each user on its own line
var html = arrayToList(result, chr(10));
// output the JSON result
writeOutput(html);
}
public array function searchUsers(required string search) {
// normally this would query the db,
// but for this demo I'll just create a static array of users
var users = [
{id="1", name="Adam", email="adam@email.com"},
{id="2", name="Bob", email="bob@email.com"},
{id="3", name="Brady", email="brady@email.com"},
{id="4", name="John", email="john@email.com"},
{id="5", name="Kaitlyn", email="kaitlyn@email.com"},
{id="6", name="Leanne", email="leanne@email.com"},
{id="7", name="Lisa", email="lisa@email.com"},
{id="8", name="Mike", email="mike@email.com"},
{id="9", name="Nate", email="nate@email.com"},
{id="10", name="Ryan", email="ryan@email.com"},
{id="11", name="Sean", email="sean@email.com"},
{id="12", name="Tony", email="tony@email.com"},
{id="13", name="Tyler", email="tyler@email.com"}
];
return users;
}
}
On a side note, JSON.parse() is a built-in function only available to newer browsers, like Firefox 3.5 and IE 8.0. Does anybody know of a good plugin to accommodate older browsers? Something similar to Prototype's String.evalJSON would be preferred.