Full disclaimer, most of the code in this answer was copied(then altered) from the jQuery UI API manual page for Autocomplete.
That out of the way, your autocomplete is not allowing for multiple selections for a simple reason: it requires a custom handler to be set up in order for such to happen, and you never set up that handler.
Secondly, the code is doing what its supposed to.. You specifically select the SubCategoryID
property from your item
object, which given your comment, contains the ID of the item.
Given what you have said in the question and comments, I would surmise this is not your goal. So, that in mind, here is the correct code to do what I think you want to achieve. I'm putting in comments to explain what I do(and again to note, the core of this is taken from the API page, with a slight alteration):
$(function () {
$('#city').autocomplete({
source: function (request, response) {
$.ajax({
url: "Home/GetWhatever",
data: "{ pre: request.term }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
SubCategoryName: item.SubCategoryName,
SubCategoryID: item.SubCategoryID,
json: item
};
}));
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
focus: function (event, ui) {
/**
* Here is the modifications I altered from the API manual page;
* all I really added was extra focus event handling code and
* an id field, if you just want the ids to be added to a
* hidden input or such.
*/
//Grab the current value of the input(s) and turn them into arrays
var terms = this.value.split(/,\s*/),
ids = $("#cityids").val().split(/,\s*/);
//Remove the current input ^ This is regex, it matches by
terms.pop(); // a comma followed by zero or
ids.pop(); // more spaces.
//Add the selected item to the end of the array(s)
terms.push(ui.item.SubCategoryName);
ids.push(ui.item.SubCategoryID);
//Set the value of the inputs to the new strings.
$("#city").val(terms.join(", "));
$("#cityids").val(ids.join(", "));
return false;
},
select: function (event, ui) {
//Grab the current values of the input(s) and turn them into arrays
var terms = this.value.split(/,\s*/),
ids = $("#cityids").val().split(/,\s*/);
//Remove the current input
terms.pop();
ids.pop();
//Add the selected item to the end of the array(s)
terms.push(ui.item.SubCategoryName);
ids.push(ui.item.SubCategoryID);
//Add placeholder to get the comma-and-space at the end
terms.push("");
ids.push("");
//Set the value of the inputs to the new strings.
$("#city").val(terms.join(", "));
$("#cityids").val(ids.join(", "));
return false;
},
}).data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li>")
.append("<a>" + item.SubCategoryName + " " + item.SubCategoryID + "</a>")
.appendTo(ul);
};
});
Update:
In regards to my oversight regarding the search terms, the following should do it, as well as the delete term bit;
Replace your 'success' handler code/content with the following:
var terms = request.term.split(/,\s*/),
cur_term;
// Get the current term
if (terms[terms.length - 1] == "") {
cur_term = terms[terms.length - 2];
} else if (terms.length > 1) {
cur_term = terms[terms.length - 1]
} else {
cur_term = request.term;
}
response($.map(data, function (item) {
var reqterm = $.ui.autocomplete.escapeRegex(cur_term),
//escape any regex
reg = new RegExp("^"+reqterm,"gi"),
//create the regex object with current term
match = item.SubCategoryName.match(reg);
//match the item name against the regex
if (match !== null) {
return { // match found, add object
SubCategoryName: item.SubCategoryName,
SubCategoryID: item.SubCategoryID,
json: item
}
} else {
return null; // No search term found, remove item from array.
}
}));
The above searches for the current term in the data, only returning matches if any are found.
Secondly, insert this code before your .data()
code, so it goes between the })
and .data()
; example: }).data(/*etc*/)
becomes }).keydown(/*etc*/).data(/*etc*/)
.keydown(function(e) {
var key = e.which;
if (key == 8) { // backspace, add keycodes here to account for all keyboards
var terms = $("#city").val().split(/,\s*/), //current terms
ids = $("#cityids").val().split(/,\s*/), //current ids
placeholder = terms[terms.length - 1]; //current placeholder
// remove the current input, as well as the placeholder if applicable
terms.pop();
ids.pop();
if (placeholder == "") {
terms.pop();
ids.pop();
}
// add the placeholders back
terms.push(" ");
ids.push(" ");
$("#city").val(terms.join(", "));
$("#cityids").val(ids.join(", "));
}
})