This is the demo page for a rich autocompletion post on the blog for The Bungee Book. Read the full post here.
new Ajax.Autocompleter('edtBasic', 'basicCompletions', 'basic_completion.php', { method: 'get' });
Each result item sent back from the server looks something like this (the <strong> tag delimits the part matching the current input):
<li>É<strong>lo</strong>die</li>
The returned items use <strong> elements to surround matching parts, but these are ignored by regular text extraction, which essentially strips tags inside the item’s <li>.
new Ajax.Autocompleter('edtTooBasic', 'tooBasicCompletions', 'rich_completion.php', { method: 'get' });
The somewhat richer contents for a result item would look like the following:
<li>
<img src="avatar_elodie.png" alt="" />
<span class="name">É<strong>lo</strong>die</a></span><br />
<span class="age">Age 27</span>
</li>
The trouble with rich contents is, the whole textual contents of the item will be used! This includes whitespace, carriage returns and line breaks, etc. Essentially, the concatenation of all textual contents within the DOM fragment for the <li> element. This results in unusuable text completions.
new Ajax.Autocompleter('edtFiltered', 'filteredCompletions', 'rich_completion.php', {
method: 'get', select: 'name'
});
In order to filter the resulting contents, one built-in way would be to mark every undesirable text fragment with the CSS class “informal.” However, this quickly becomes impractical for large fragments or when content to be included sites inside content to be otherwise ignored. We’ll instead use a specific CSS class name to mark the textual parts we mean to include. Here we actually already have such a class: “name.” We specify this class for the select option.
Try it out below:
There, only the name makes it in! Much better, wouldn’t you say?
This is pretty nice, however sometimes you’ll want your UI to reflect more than textual fragments for the completion choice. Consider the following common scenario:
So how do we achieve this? Well, we use the afterUpdateElement callback. It is triggered after the normal completion process, and receives the selected <li> element (hence its DOM fragment) as its second argument (the first one is the edit zone you created your autocompleter around). From there, using appropriate DOM navigation, you can do any number of custom completions. Consider the following example, where we re-use the person’s image and age, too:
new Ajax.Autocompleter('edtMultiple', 'multipleCompletions', 'rich_completion.php', {
method: 'get', select: 'name', afterUpdateElement: function(editor, item) {
var mugshot = editor.previous('img'), ageZone = editor.next('.age');
mugshot.src = item.down('img').src;
ageZone.update(item.down('.age').innerHTML);
}
});
Pretty cool, uh?