YUI recommends YUI 3.

YUI 2 has been deprecated since 2011. This site acts as an archive for files and documentation.

YUI Library Home

YUI Library Examples: AutoComplete Control: FunctionDataSource to Search Multiple Fields of an Address Book at Runtime

AutoComplete Control: FunctionDataSource to Search Multiple Fields of an Address Book at Runtime

This example uses a FunctionDataSource to perform string matching against multiple fields of a contacts database at runtime. Since the data for this example is loaded into local memory, queries should be quite fast to return data, but use of the custom function allows a more complex search algorithm. A custom formatter allows users to see their search term within the result set. An itemSelectEvent handler is used to update the input field with a custom value and to populate a hidden form field with the selected contact's ID for eventually submitting back to a server.

Implementers who are working with data from third-party sources, user input data, or otherwise untrustworthy sources should be sure to read the Security Considerations section of the AutoComplete user guide.

Sample Code

Data:

1var myContacts = [ 
2    {id:0, fname:"Alice", lname:"Abrams", nname:"ace"}, 
3    {id:1, fname:"Abraham", lname:"Axelrod", nname:"Abe"}, 
4    {id:2, fname:"Bruce", lname:"Baxter", nname:null}, 
5    {id:3, fname:"Robert", lname:"Brown", nname:"Bob"}, 
6    {id:4, fname:"Carl", lname:"Carlson", nname:null}, 
7    {id:5, fname:"Charlie", lname:"Chaplin", nname:"Chuck"}, 
8    {id:6, fname:"Darla", lname:"Darling", nname:null}, 
9    {id:7, fname:"David", lname:"Dashing", nname:"Dave"}, 
10    {id:8, fname:"Egbert", lname:"Excellent", nname:null}, 
11    {id:9, fname:"Engleberg", lname:"Humperdink", nname:null
12]; 
view plain | print | ?

CSS:

1#myAutoComplete { 
2    width:15em/* set width here or else widget will expand to fit its container */ 
3    padding-bottom:2em
4} 
5.match { 
6    font-weight:bold
7} 
view plain | print | ?

Markup:

1<label for="myInput">Find a contact:</label> 
2<div id="myAutoComplete"
3    <input id="myInput" type="text"
4    <div id="myContainer"></div> 
5    <input id="myHidden" type="hidden"
6</div> 
view plain | print | ?

JavaScript:

1YAHOO.example.FnMultipleFields = function(){ 
2    var myContacts = [ 
3        {id:0, fname:"Alice", lname:"Abrams", nname:"ace"}, 
4        {id:1, fname:"Abraham", lname:"Axelrod", nname:"Abe"}, 
5        {id:2, fname:"Bruce", lname:"Baxter", nname:null}, 
6        {id:3, fname:"Robert", lname:"Brown", nname:"Bob"}, 
7        {id:4, fname:"Carl", lname:"Carlson", nname:null}, 
8        {id:5, fname:"Charlie", lname:"Chaplin", nname:"Chuck"}, 
9        {id:6, fname:"Darla", lname:"Darling", nname:null}, 
10        {id:7, fname:"David", lname:"Dashing", nname:"Dave"}, 
11        {id:8, fname:"Egbert", lname:"Excellent", nname:null}, 
12        {id:9, fname:"Engleberg", lname:"Humperdink", nname:null
13    ]; 
14     
15    // Define a custom search function for the DataSource 
16    var matchNames = function(sQuery) { 
17        // Case insensitive matching 
18        var query = sQuery.toLowerCase(), 
19            contact, 
20            i=0, 
21            l=myContacts.length, 
22            matches = []; 
23         
24        // Match against each name of each contact 
25        for(; i<l; i++) { 
26            contact = myContacts[i]; 
27            if((contact.fname.toLowerCase().indexOf(query) > -1) || 
28                (contact.lname.toLowerCase().indexOf(query) > -1) || 
29                (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) { 
30                matches[matches.length] = contact; 
31            } 
32        } 
33 
34        return matches; 
35    }; 
36 
37    // Use a FunctionDataSource 
38    var oDS = new YAHOO.util.FunctionDataSource(matchNames); 
39    oDS.responseSchema = { 
40        fields: ["id""fname""lname""nname"
41    } 
42 
43    // Instantiate AutoComplete 
44    var oAC = new YAHOO.widget.AutoComplete("myInput""myContainer", oDS); 
45    oAC.useShadow = true
46    oAC.resultTypeList = false
47     
48     
49    // Custom formatter to highlight the matching letters 
50    oAC.formatResult = function(oResultData, sQuery, sResultMatch) { 
51        var query = sQuery.toLowerCase(), 
52            fname = oResultData.fname, 
53            lname = oResultData.lname, 
54            nname = oResultData.nname || ""// Guard against null value 
55            query = sQuery.toLowerCase(), 
56            fnameMatchIndex = fname.toLowerCase().indexOf(query), 
57            lnameMatchIndex = lname.toLowerCase().indexOf(query), 
58            nnameMatchIndex = nname.toLowerCase().indexOf(query), 
59            displayfname, displaylname, displaynname; 
60             
61        if(fnameMatchIndex > -1) { 
62            displayfname = highlightMatch(fname, query, fnameMatchIndex); 
63        } 
64        else { 
65            displayfname = fname; 
66        } 
67 
68        if(lnameMatchIndex > -1) { 
69            displaylname = highlightMatch(lname, query, lnameMatchIndex); 
70        } 
71        else { 
72            displaylname = lname; 
73        } 
74 
75        if(nnameMatchIndex > -1) { 
76            displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")"
77        } 
78        else { 
79            displaynname = nname ? "(" + nname + ")" : ""
80        } 
81 
82        return displayfname + " " + displaylname + " " + displaynname; 
83         
84    }; 
85     
86    // Helper function for the formatter 
87    var highlightMatch = function(full, snippet, matchindex) { 
88        return full.substring(0, matchindex) +  
89                "<span class='match'>" +  
90                full.substr(matchindex, snippet.length) +  
91                "</span>" + 
92                full.substring(matchindex + snippet.length); 
93    }; 
94 
95    // Define an event handler to populate a hidden form field 
96    // when an item gets selected and populate the input field 
97    var myHiddenField = YAHOO.util.Dom.get("myHidden"); 
98    var myHandler = function(sType, aArgs) { 
99        var myAC = aArgs[0]; // reference back to the AC instance 
100        var elLI = aArgs[1]; // reference to the selected LI element 
101        var oData = aArgs[2]; // object literal of selected item's result data 
102         
103        // update hidden form field with the selected item's ID 
104        myHiddenField.value = oData.id; 
105         
106        myAC.getInputEl().value = oData.fname + " " + oData.lname + (oData.nname ? " (" + oData.nname + ")" : ""); 
107    }; 
108    oAC.itemSelectEvent.subscribe(myHandler); 
109     
110    return { 
111        oDS: oDS, 
112        oAC: oAC  
113    }; 
114}(); 
view plain | print | ?

Configuration for This Example

You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.

Copyright © 2011 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings