Skip to content

Commit 80e940f

Browse files
author
Polo
committed
Added an optional no-suggestions notice when no matching results
This feature aims to improve user experience and plugin's responsiveness by providing instant feedback for empty searches.
1 parent 702bc0e commit 80e940f

File tree

5 files changed

+61
-11
lines changed

5 files changed

+61
-11
lines changed

content/styles.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
.autocomplete-suggestions { border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; -webkit-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); -moz-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); }
55
.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
6+
.autocomplete-no-suggestion { padding: 2px 5px;}
67
.autocomplete-selected { background: #F0F0F0; }
78
.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }
89

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ The standard jquery.autocomplete.js file is around 2.7KB when minified via Closu
4444
* `autoSelectFirst`: if set to `true`, first item will be selected when showing suggestions. Default value `false`.
4545
* `appendTo`: container where suggestions will be appended. Default value `body`. Can be jQuery object, selector or html element. Make sure to set `position: absolute` or `position: relative` for that element.
4646
* `dataType`: type of data returned from server. Either 'text' (default) or 'jsonp', which will cause the autocomplete to use jsonp. You may return a json object in your callback when using jsonp.
47+
* `showNoSuggestionNotice`: Default `false`. When no matching results, display a notification label.
48+
* `noSuggestionNotice`: Default `No results`. Text for no matching results label.
4749

4850
Autocomplete instance has following methods:
4951

scripts/demo.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ $(function () {
5252
minChars: 0,
5353
onSelect: function (suggestion) {
5454
$('#selection').html('You selected: ' + suggestion.value + ', ' + suggestion.data);
55-
}
55+
},
56+
showNoSuggestionNotice: true,
57+
noSuggestionNotice: 'Sorry, no matching results',
5658
});
5759

5860
// Initialize autocomplete with custom appendTo:

spec/autocompleteBehavior.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,4 +654,24 @@ describe('Autocomplete', function () {
654654
expect(ajaxCount).toBe(2);
655655
});
656656
});
657+
658+
it('Should display no suggestion notice when no matching results', function () {
659+
var input = document.createElement('input'),
660+
options = {
661+
lookup: [{ value: 'Colombia', data: 'Spain' }],
662+
showNoSuggestionNotice: true,
663+
noSuggestionNotice: 'Sorry, no matching results'
664+
},
665+
autocomplete = new $.Autocomplete(input, options),
666+
suggestionsContainer = $(autocomplete.suggestionsContainer)
667+
668+
input.value = 'Jamaica';
669+
autocomplete.onValueChange();
670+
671+
expect(autocomplete.visible).toBe(true);
672+
expect(autocomplete.selectedIndex).toBe(-1)
673+
expect(suggestionsContainer.find('.autocomplete-no-suggestion').length).toBe(1)
674+
expect(suggestionsContainer.find('.autocomplete-no-suggestion').text()).toBe('Sorry, no matching results')
675+
});
676+
657677
});

src/jquery.autocomplete.js

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@
8383
paramName: 'query',
8484
transformResult: function (response) {
8585
return typeof response === 'string' ? $.parseJSON(response) : response;
86-
}
86+
},
87+
showNoSuggestionNotice: false,
88+
noSuggestionNotice: 'No results'
8789
};
8890

8991
// Shared variables:
@@ -544,7 +546,7 @@
544546

545547
suggest: function () {
546548
if (this.suggestions.length === 0) {
547-
this.hide();
549+
this.options.showNoSuggestionNotice ? this.noSuggestions() : this.hide();
548550
return;
549551
}
550552

@@ -573,14 +575,7 @@
573575
html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value) + '</div>';
574576
});
575577

576-
// If width is auto, adjust width before displaying suggestions,
577-
// because if instance was created before input had width, it will be zero.
578-
// Also it adjusts if input width has changed.
579-
// -2px to account for suggestions border.
580-
if (options.width === 'auto') {
581-
width = that.el.outerWidth() - 2;
582-
container.width(width > 0 ? width : 300);
583-
}
578+
this.adjustContainerWidth();
584579

585580
container.html(html);
586581

@@ -600,6 +595,36 @@
600595
that.findBestHint();
601596
},
602597

598+
noSuggestions: function() {
599+
var that = this,
600+
container = $(that.suggestionsContainer),
601+
html = '',
602+
width;
603+
604+
html += '<div class="autocomplete-no-suggestion">' + this.options.noSuggestionNotice + '</div>';
605+
606+
this.adjustContainerWidth();
607+
container.html(html);
608+
container.show();
609+
that.visible = true;
610+
},
611+
612+
adjustContainerWidth: function() {
613+
var that = this,
614+
options = that.options,
615+
width,
616+
container = $(that.suggestionsContainer)
617+
618+
// If width is auto, adjust width before displaying suggestions,
619+
// because if instance was created before input had width, it will be zero.
620+
// Also it adjusts if input width has changed.
621+
// -2px to account for suggestions border.
622+
if (options.width === 'auto') {
623+
width = that.el.outerWidth() - 2;
624+
container.width(width > 0 ? width : 300);
625+
}
626+
},
627+
603628
findBestHint: function () {
604629
var that = this,
605630
value = that.el.val().toLowerCase(),

0 commit comments

Comments
 (0)