Jquery autocomplete with category selection
I am using jquery automplete with category option, everything works fine. Now I want to make the categories select-able. I went through a lot of things but nothing seems to work. Is there a way to make the category of choice not a shortcut.
My code looks like this:
$.widget("custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function (ul, items) {
var self = this;
var currentCategory = "";
$.each(items, function (index, item) {
if (item.category != currentCategory) {
ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
currentCategory = item.category;
}
self._renderItem(ul, item);
});
},
});
$('#city').catcomplete({
delay:0,
source : function(request, response) {
$.ajax({
url : '${createLink(controller:"city", action:"ajaxData")}',
data : {
term : request.term
},
dataType : "json",
success : function(data) {
if (data.length > 0) {
response( $.map( data, function( item ) {
return {
label: item.label,
value: item.category,
category: item.category,
}
}));
}
else{
response([{ category: 'No results found', val: "",label:""}]);
}
}
});
},
focus: function(event, ui) {
$("#city").val(ui.item.category);
return false;
} ,
select: function( event, ui ) {
window.location.href = ui.item.category;
},
});
+3
source to share
2 answers
This will fix your problem, but may not be the best solution.
What I've done
- added a click event listener for the category parameter and it will call
selectHandler()
to handle selecting an option from the autocomplete list. - creating a category option as a menu item by adding a class
ui-menu-item
to the tag<li>
that will provide the category options with the same visual effects as the other options in the list.
Live Demo @JSFiddle:
http://jsfiddle.net/dreamweiver/bp0x1yc4/11/
JS code:
$(document).on('click', '.ui-autocomplete-category', function () {
$("#search").val($(this).html());
$("#search").catcomplete("close");
selectHandler($(this).html());
});
var selectHandler = function (data) {
//process selected data
console.log("selected value: " + data);
};
Happy coding :)
+1
source to share
I have configured autocomplete based on requirement
$(function () {
$.widget("custom.catcomplete", $.ui.autocomplete, {
_create: function () {
this._super();
this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
this.widget().addClass("sw_autocomplete");
},
_renderMenu: function (ul, items) {
var that = this,
currentCategory = "";
$.each(items, function (index, item) {
var li;
var itemType = "";
if (item.isCity) {
itemType = "City";
}
if (item.country == '-sky') {
itemType = "Country";
return;
}
li = that.__renderItemData(ul, item, itemType);
if (item.category) {
li.attr("aria-label", item.category + " : " + item.label);
li.attr("style", "padding-left:20px;");
}
});
},
__renderItemData: function (ul, item, itemType) {
return this.__renderItem(ul, item, itemType).data("ui-autocomplete-item", item);
},
__renderItem: function (ul, item, itemType) {
if (itemType == "Country") {
return $("<li>")
.append($("<a>").html("<i class='fa fa-globe' aria-hidden='true'></i><span>" + item.label + "</span>"))
.appendTo(ul);
}
if (itemType == "City") {
return $("<li>")
.append($("<a>").html("<i class='fa fa-map-marker' aria-hidden='true'></i><span>" + item.label + "</span>"))
.appendTo(ul);
}
else {
return $("<li>")
.append($("<a>").html("<i class='fa fa-plane' aria-hidden='true'></i><span>" + item.label + "</span>"))
.appendTo(ul);
}
},
});
var UniqueCategory = "";
var UniqueCityId = "";
$("#flightFrom").catcomplete({
delay: 0,
select: function (event, ui) {
$("#flightFrom").removeClass('error');
},
open: function () {
$("#flightFrom").removeClass('error');
},
source: function (request, response) {
$.ajax({
url: "http://partners.api.skyscanner.net/apiservices/xd/autosuggest/v1.0/UK/GBP/en-GB/",
dataType: "jsonp",
data: {
query: request.term
},
success: function (data) {
UniqueCategory = "";
UniqueCityId = "";
response($.map(data.Places, function (item) {
var sourceAirport = "";
if (item.PlaceId == item.CityId) {
UniqueCategory = item.PlaceName + ", " + item.CountryName + " (" + item.PlaceId + ")";
UniqueCityId = item.CityId;
return {
label: item.PlaceName + ", " + item.CountryName + " (" + item.PlaceId.replace("-sky", "") + ")",
value: item.PlaceName + ", " + item.CountryName + " (" + item.PlaceId.replace("-sky", "") + ")",
isCity: true,
sourceAirport: item.PlaceId
};
}
else {
if (item.CityId == UniqueCityId) {
return {
label: item.PlaceName + ", " + item.CountryName + " (" + item.PlaceId.replace("-sky", "") + ")",
value: item.PlaceName + ", " + item.CountryName + " (" + item.PlaceId.replace("-sky", "") + ")",
category: UniqueCategory,
sourceAirport: item.PlaceId
};
}
return {
label: item.PlaceName + ", " + item.CountryName + " (" + item.PlaceId.replace("-sky", "") + ")",
value: item.PlaceName + ", " + item.CountryName + " (" + item.PlaceId.replace("-sky", "") + ")",
country: item.CityId,
sourceAirport: item.PlaceId
};
}
}));
},
});
},
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<label for="flightFrom">Flight From: </label>
<input id="flightFrom" style="width:300px">
Enter "New" or "London" in the input field.
This is the same one we used in one of the solutions.
0
source to share