Skip to content
This repository was archived by the owner on May 21, 2025. It is now read-only.

Commit d4c42c3

Browse files
committed
Fix issue #2: matchClass throwing errors for remote api
1 parent 068cd33 commit d4c42c3

5 files changed

Lines changed: 292 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ var app = angular.module('app', ["angucomplete-alt"]);
7272
| image-field | The name of the field in the JSON objects returned back that should be used for displaying an image in the autocomplete list | No | pic |
7373
| minlength | The minimum length of string required before searching | No | 3 |
7474
| input-class | The classes to use for styling the input box | No | form-control |
75+
| match-class | If it is assigned, matching part of title is highlighted with given class style | No | highlight |
7576
| local-data | The local data variable to use from your controller. Should be an array of objects | No | countriesList |
7677
| search-fields | The fields from your local data to search on (comma separate them) | No | title,description |
7778
| remote-url-request-formatter | A function that takes a query string and returns parameter(s) for GET. It should take the query string as argument and returns a key-value object.| No | Suppose if you need to send a query keyword and a timestamp to search API, you can write a function like this in the parent scope. $scope.dataFormatFn = function(str) { return {q: str, timestamp: +new Date()}; } |

angucomplete-alt.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ angular.module('angucomplete-alt', [] ).directive('angucompleteAlt', ['$parse',
108108
};
109109

110110
scope.processResults = function(responseData, str) {
111-
var titleFields, titleCode, i, t, description, image, text, re, strPart;
111+
var titleFields, titleCode, i, t, description, image, text, re, strPart, matches;
112112

113113
if (responseData && responseData.length > 0) {
114114
scope.results = [];
@@ -139,8 +139,14 @@ angular.module('angucomplete-alt', [] ).directive('angucompleteAlt', ['$parse',
139139
text = titleCode.join(' ');
140140
if (scope.matchClass) {
141141
re = new RegExp(str, 'i');
142-
strPart = text.match(re)[0];
143-
text = $sce.trustAsHtml(text.replace(re, '<span class="'+ scope.matchClass +'">'+ strPart +'</span>'));
142+
matches = text.match(re);
143+
if (matches) {
144+
strPart = matches[0];
145+
text = $sce.trustAsHtml(text.replace(re, '<span class="'+ scope.matchClass +'">'+ strPart +'</span>'));
146+
}
147+
else {
148+
text = $sce.trustAsHtml(text);
149+
}
144150
}
145151

146152
scope.results[scope.results.length] = {

example/countries.json

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
{"data":
2+
[
3+
{"name": "Afghanistan", "code": "AF"},
4+
{"name": "Aland Islands", "code": "AX"},
5+
{"name": "Albania", "code": "AL"},
6+
{"name": "Algeria", "code": "DZ"},
7+
{"name": "American Samoa", "code": "AS"},
8+
{"name": "AndorrA", "code": "AD"},
9+
{"name": "Angola", "code": "AO"},
10+
{"name": "Anguilla", "code": "AI"},
11+
{"name": "Antarctica", "code": "AQ"},
12+
{"name": "Antigua and Barbuda", "code": "AG"},
13+
{"name": "Argentina", "code": "AR"},
14+
{"name": "Armenia", "code": "AM"},
15+
{"name": "Aruba", "code": "AW"},
16+
{"name": "Australia", "code": "AU"},
17+
{"name": "Austria", "code": "AT"},
18+
{"name": "Azerbaijan", "code": "AZ"},
19+
{"name": "Bahamas", "code": "BS"},
20+
{"name": "Bahrain", "code": "BH"},
21+
{"name": "Bangladesh", "code": "BD"},
22+
{"name": "Barbados", "code": "BB"},
23+
{"name": "Belarus", "code": "BY"},
24+
{"name": "Belgium", "code": "BE"},
25+
{"name": "Belize", "code": "BZ"},
26+
{"name": "Benin", "code": "BJ"},
27+
{"name": "Bermuda", "code": "BM"},
28+
{"name": "Bhutan", "code": "BT"},
29+
{"name": "Bolivia", "code": "BO"},
30+
{"name": "Bosnia and Herzegovina", "code": "BA"},
31+
{"name": "Botswana", "code": "BW"},
32+
{"name": "Bouvet Island", "code": "BV"},
33+
{"name": "Brazil", "code": "BR"},
34+
{"name": "British Indian Ocean Territory", "code": "IO"},
35+
{"name": "Brunei Darussalam", "code": "BN"},
36+
{"name": "Bulgaria", "code": "BG"},
37+
{"name": "Burkina Faso", "code": "BF"},
38+
{"name": "Burundi", "code": "BI"},
39+
{"name": "Cambodia", "code": "KH"},
40+
{"name": "Cameroon", "code": "CM"},
41+
{"name": "Canada", "code": "CA"},
42+
{"name": "Cape Verde", "code": "CV"},
43+
{"name": "Cayman Islands", "code": "KY"},
44+
{"name": "Central African Republic", "code": "CF"},
45+
{"name": "Chad", "code": "TD"},
46+
{"name": "Chile", "code": "CL"},
47+
{"name": "China", "code": "CN"},
48+
{"name": "Christmas Island", "code": "CX"},
49+
{"name": "Cocos (Keeling) Islands", "code": "CC"},
50+
{"name": "Colombia", "code": "CO"},
51+
{"name": "Comoros", "code": "KM"},
52+
{"name": "Congo", "code": "CG"},
53+
{"name": "Congo, The Democratic Republic of the", "code": "CD"},
54+
{"name": "Cook Islands", "code": "CK"},
55+
{"name": "Costa Rica", "code": "CR"},
56+
{"name": "Cote D\"Ivoire", "code": "CI"},
57+
{"name": "Croatia", "code": "HR"},
58+
{"name": "Cuba", "code": "CU"},
59+
{"name": "Cyprus", "code": "CY"},
60+
{"name": "Czech Republic", "code": "CZ"},
61+
{"name": "Denmark", "code": "DK"},
62+
{"name": "Djibouti", "code": "DJ"},
63+
{"name": "Dominica", "code": "DM"},
64+
{"name": "Dominican Republic", "code": "DO"},
65+
{"name": "Ecuador", "code": "EC"},
66+
{"name": "Egypt", "code": "EG"},
67+
{"name": "El Salvador", "code": "SV"},
68+
{"name": "Equatorial Guinea", "code": "GQ"},
69+
{"name": "Eritrea", "code": "ER"},
70+
{"name": "Estonia", "code": "EE"},
71+
{"name": "Ethiopia", "code": "ET"},
72+
{"name": "Falkland Islands (Malvinas)", "code": "FK"},
73+
{"name": "Faroe Islands", "code": "FO"},
74+
{"name": "Fiji", "code": "FJ"},
75+
{"name": "Finland", "code": "FI"},
76+
{"name": "France", "code": "FR"},
77+
{"name": "French Guiana", "code": "GF"},
78+
{"name": "French Polynesia", "code": "PF"},
79+
{"name": "French Southern Territories", "code": "TF"},
80+
{"name": "Gabon", "code": "GA"},
81+
{"name": "Gambia", "code": "GM"},
82+
{"name": "Georgia", "code": "GE"},
83+
{"name": "Germany", "code": "DE"},
84+
{"name": "Ghana", "code": "GH"},
85+
{"name": "Gibraltar", "code": "GI"},
86+
{"name": "Greece", "code": "GR"},
87+
{"name": "Greenland", "code": "GL"},
88+
{"name": "Grenada", "code": "GD"},
89+
{"name": "Guadeloupe", "code": "GP"},
90+
{"name": "Guam", "code": "GU"},
91+
{"name": "Guatemala", "code": "GT"},
92+
{"name": "Guernsey", "code": "GG"},
93+
{"name": "Guinea", "code": "GN"},
94+
{"name": "Guinea-Bissau", "code": "GW"},
95+
{"name": "Guyana", "code": "GY"},
96+
{"name": "Haiti", "code": "HT"},
97+
{"name": "Heard Island and Mcdonald Islands", "code": "HM"},
98+
{"name": "Holy See (Vatican City State)", "code": "VA"},
99+
{"name": "Honduras", "code": "HN"},
100+
{"name": "Hong Kong", "code": "HK"},
101+
{"name": "Hungary", "code": "HU"},
102+
{"name": "Iceland", "code": "IS"},
103+
{"name": "India", "code": "IN"},
104+
{"name": "Indonesia", "code": "ID"},
105+
{"name": "Iran, Islamic Republic Of", "code": "IR"},
106+
{"name": "Iraq", "code": "IQ"},
107+
{"name": "Ireland", "code": "IE"},
108+
{"name": "Isle of Man", "code": "IM"},
109+
{"name": "Israel", "code": "IL"},
110+
{"name": "Italy", "code": "IT"},
111+
{"name": "Jamaica", "code": "JM"},
112+
{"name": "Japan", "code": "JP"},
113+
{"name": "Jersey", "code": "JE"},
114+
{"name": "Jordan", "code": "JO"},
115+
{"name": "Kazakhstan", "code": "KZ"},
116+
{"name": "Kenya", "code": "KE"},
117+
{"name": "Kiribati", "code": "KI"},
118+
{"name": "Korea, Democratic People\"S Republic of", "code": "KP"},
119+
{"name": "Korea, Republic of", "code": "KR"},
120+
{"name": "Kuwait", "code": "KW"},
121+
{"name": "Kyrgyzstan", "code": "KG"},
122+
{"name": "Lao People\"S Democratic Republic", "code": "LA"},
123+
{"name": "Latvia", "code": "LV"},
124+
{"name": "Lebanon", "code": "LB"},
125+
{"name": "Lesotho", "code": "LS"},
126+
{"name": "Liberia", "code": "LR"},
127+
{"name": "Libyan Arab Jamahiriya", "code": "LY"},
128+
{"name": "Liechtenstein", "code": "LI"},
129+
{"name": "Lithuania", "code": "LT"},
130+
{"name": "Luxembourg", "code": "LU"},
131+
{"name": "Macao", "code": "MO"},
132+
{"name": "Macedonia, The Former Yugoslav Republic of", "code": "MK"},
133+
{"name": "Madagascar", "code": "MG"},
134+
{"name": "Malawi", "code": "MW"},
135+
{"name": "Malaysia", "code": "MY"},
136+
{"name": "Maldives", "code": "MV"},
137+
{"name": "Mali", "code": "ML"},
138+
{"name": "Malta", "code": "MT"},
139+
{"name": "Marshall Islands", "code": "MH"},
140+
{"name": "Martinique", "code": "MQ"},
141+
{"name": "Mauritania", "code": "MR"},
142+
{"name": "Mauritius", "code": "MU"},
143+
{"name": "Mayotte", "code": "YT"},
144+
{"name": "Mexico", "code": "MX"},
145+
{"name": "Micronesia, Federated States of", "code": "FM"},
146+
{"name": "Moldova, Republic of", "code": "MD"},
147+
{"name": "Monaco", "code": "MC"},
148+
{"name": "Mongolia", "code": "MN"},
149+
{"name": "Montserrat", "code": "MS"},
150+
{"name": "Morocco", "code": "MA"},
151+
{"name": "Mozambique", "code": "MZ"},
152+
{"name": "Myanmar", "code": "MM"},
153+
{"name": "Namibia", "code": "NA"},
154+
{"name": "Nauru", "code": "NR"},
155+
{"name": "Nepal", "code": "NP"},
156+
{"name": "Netherlands", "code": "NL"},
157+
{"name": "Netherlands Antilles", "code": "AN"},
158+
{"name": "New Caledonia", "code": "NC"},
159+
{"name": "New Zealand", "code": "NZ"},
160+
{"name": "Nicaragua", "code": "NI"},
161+
{"name": "Niger", "code": "NE"},
162+
{"name": "Nigeria", "code": "NG"},
163+
{"name": "Niue", "code": "NU"},
164+
{"name": "Norfolk Island", "code": "NF"},
165+
{"name": "Northern Mariana Islands", "code": "MP"},
166+
{"name": "Norway", "code": "NO"},
167+
{"name": "Oman", "code": "OM"},
168+
{"name": "Pakistan", "code": "PK"},
169+
{"name": "Palau", "code": "PW"},
170+
{"name": "Palestinian Territory, Occupied", "code": "PS"},
171+
{"name": "Panama", "code": "PA"},
172+
{"name": "Papua New Guinea", "code": "PG"},
173+
{"name": "Paraguay", "code": "PY"},
174+
{"name": "Peru", "code": "PE"},
175+
{"name": "Philippines", "code": "PH"},
176+
{"name": "Pitcairn", "code": "PN"},
177+
{"name": "Poland", "code": "PL"},
178+
{"name": "Portugal", "code": "PT"},
179+
{"name": "Puerto Rico", "code": "PR"},
180+
{"name": "Qatar", "code": "QA"},
181+
{"name": "Reunion", "code": "RE"},
182+
{"name": "Romania", "code": "RO"},
183+
{"name": "Russian Federation", "code": "RU"},
184+
{"name": "RWANDA", "code": "RW"},
185+
{"name": "Saint Helena", "code": "SH"},
186+
{"name": "Saint Kitts and Nevis", "code": "KN"},
187+
{"name": "Saint Lucia", "code": "LC"},
188+
{"name": "Saint Pierre and Miquelon", "code": "PM"},
189+
{"name": "Saint Vincent and the Grenadines", "code": "VC"},
190+
{"name": "Samoa", "code": "WS"},
191+
{"name": "San Marino", "code": "SM"},
192+
{"name": "Sao Tome and Principe", "code": "ST"},
193+
{"name": "Saudi Arabia", "code": "SA"},
194+
{"name": "Senegal", "code": "SN"},
195+
{"name": "Serbia and Montenegro", "code": "CS"},
196+
{"name": "Seychelles", "code": "SC"},
197+
{"name": "Sierra Leone", "code": "SL"},
198+
{"name": "Singapore", "code": "SG"},
199+
{"name": "Slovakia", "code": "SK"},
200+
{"name": "Slovenia", "code": "SI"},
201+
{"name": "Solomon Islands", "code": "SB"},
202+
{"name": "Somalia", "code": "SO"},
203+
{"name": "South Africa", "code": "ZA"},
204+
{"name": "South Georgia and the South Sandwich Islands", "code": "GS"},
205+
{"name": "Spain", "code": "ES"},
206+
{"name": "Sri Lanka", "code": "LK"},
207+
{"name": "Sudan", "code": "SD"},
208+
{"name": "Suriname", "code": "SR"},
209+
{"name": "Svalbard and Jan Mayen", "code": "SJ"},
210+
{"name": "Swaziland", "code": "SZ"},
211+
{"name": "Sweden", "code": "SE"},
212+
{"name": "Switzerland", "code": "CH"},
213+
{"name": "Syrian Arab Republic", "code": "SY"},
214+
{"name": "Taiwan, Province of China", "code": "TW"},
215+
{"name": "Tajikistan", "code": "TJ"},
216+
{"name": "Tanzania, United Republic of", "code": "TZ"},
217+
{"name": "Thailand", "code": "TH"},
218+
{"name": "Timor-Leste", "code": "TL"},
219+
{"name": "Togo", "code": "TG"},
220+
{"name": "Tokelau", "code": "TK"},
221+
{"name": "Tonga", "code": "TO"},
222+
{"name": "Trinidad and Tobago", "code": "TT"},
223+
{"name": "Tunisia", "code": "TN"},
224+
{"name": "Turkey", "code": "TR"},
225+
{"name": "Turkmenistan", "code": "TM"},
226+
{"name": "Turks and Caicos Islands", "code": "TC"},
227+
{"name": "Tuvalu", "code": "TV"},
228+
{"name": "Uganda", "code": "UG"},
229+
{"name": "Ukraine", "code": "UA"},
230+
{"name": "United Arab Emirates", "code": "AE"},
231+
{"name": "United Kingdom", "code": "GB"},
232+
{"name": "United States", "code": "US"},
233+
{"name": "United States Minor Outlying Islands", "code": "UM"},
234+
{"name": "Uruguay", "code": "UY"},
235+
{"name": "Uzbekistan", "code": "UZ"},
236+
{"name": "Vanuatu", "code": "VU"},
237+
{"name": "Venezuela", "code": "VE"},
238+
{"name": "Vietnam", "code": "VN"},
239+
{"name": "Virgin Islands, British", "code": "VG"},
240+
{"name": "Virgin Islands, U.S.", "code": "VI"},
241+
{"name": "Wallis and Futuna", "code": "WF"},
242+
{"name": "Western Sahara", "code": "EH"},
243+
{"name": "Yemen", "code": "YE"},
244+
{"name": "Zambia", "code": "ZM"},
245+
{"name": "Zimbabwe", "code": "ZW"}
246+
]
247+
}

example/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ <h3>Example 4 - Override Suggestions with clear result</h3>
6363

6464
</div>
6565

66+
<div class="large-padded-row">
67+
68+
<h3>Example 5 - Using dumb search API that returns all results</h3>
69+
<div class="padded-row">
70+
<angucomplete-alt id="ex5" placeholder="Search countries" pause="100" selected-object="selectedCountry" remote-url="countries.json?" remote-url-data-field="data" search-fields="name" title-field="name" description-field="type" minlength="1" input-class="form-control form-control-small" match-class="highlight" />
71+
</div>
72+
<div class="" ng-show="selectedCountry">
73+
You selected <span class="bold-span">{{selectedCountry.originalObject.name}}</span> which has a country code of <span class="bold-span">{{selectedCountry.originalObject.code}}</span>
74+
</div>
75+
76+
</div>
77+
6678
<div class="very-large-padded-row">
6779
<h5>Originally developed by Daryl Rowland (<a href="http://twitter.com/darylrowland">@darylrowland</a>)</h5>
6880
<h5>Forked by Hidenari Nozaki (<a href="http://twitter.com/ghiden">@ghiden</a>)</h5>

test/angucomplete-alt.spec.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,29 @@ describe('angucomplete-alt', function() {
261261
expect(element.isolateScope().processResults.mostRecentCall.args[0]).toEqual(results.search.data);
262262
expect(element.isolateScope().searching).toBe(false);
263263
}));
264+
265+
it('should not throw an exception when match-class is set and remote api returns bogus results (issue #2)', inject(function($httpBackend) {
266+
var element = angular.element('<div angucomplete-alt id="ex1" placeholder="Search names" selected-object="selected" remote-url="names?q=" search-fields="name" remote-url-data-field="data" title-field="name" description="type" minlength="1" match-class="highlight"/>');
267+
$compile(element)($scope);
268+
$scope.$digest();
269+
270+
var results = {data: [{name: 'tim', type: 'A'}]};
271+
$httpBackend.expectGET('names?q=a').respond(200, results);
272+
273+
var inputField = element.find('#ex1_value');
274+
var e = $.Event('keyup');
275+
e.which = 97; // letter: a
276+
277+
inputField.val('a');
278+
inputField.trigger('input');
279+
inputField.trigger(e);
280+
$timeout.flush();
281+
$httpBackend.flush();
282+
283+
$httpBackend.verifyNoOutstandingExpectation();
284+
$httpBackend.verifyNoOutstandingRequest();
285+
expect(element.isolateScope().searching).toBe(false);
286+
}));
264287
});
265288
});
266289

0 commit comments

Comments
 (0)