Goal:
jQuery AutoComplete in ASP.NET MVC Framework with callback to customize result
Platform/Environment:
Quick Solution:
Here I am simply returning a list of account names:
$('#Name').autocomplete(
$('#ajaxListMatchingAccountNamesUrl').val(), { delay: 10, minChars: 3, matchSubset: 1, matchContains: 1, cacheLength: 10, autoFill: true, mustMatch: false, selectFirst: true, max: 15 }
);
ajaxListMatchingAccountNamesUrl - this is a hidden input control in my master page that contains the url that I set as a hidden input field so as to allow the Mvc framework to set it dynamically and accessed client-side.
Here is the C# controller action:
[AcceptVerbs(HttpVerbs.Get)]
public string GetMatchingAccounts(string q)
{
if (String.IsNullOrEmpty(q))
return null;
var sb = new StringBuilder();
foreach (AccountNameIdDTO dto in _accountRepository.SearchForAccountsStartingWithNameSuffixKey(q))
{
sb.AppendLine(dto.Name);
}
return sb.ToString();
}
Complex Solution:
A situation where my account names may be the same for different acounts. In this scenario I let the server-side action append the unique ID to the name, surrounded by brackets: My Account Name (23). This way when the user selects the account, I store the name in the textbox and the ID is parsed out and stored in a protected/readonly textbox.var $accountMaintenanceWrapper = $('div#AccountMaintenanceWrapper');
$accountMaintenanceWrapper.find("#MasterAccount").autocomplete(
$('#ajaxListMatchingAccountNamesWithIdSuffixUrl').val(),
{
delay:10,
minChars:3,
matchSubset:1,
matchContains:1,
cacheLength:10,
autoFill:true,
mustMatch: false,
selectFirst : true,
max: 15,
formatResult: function(row, i, total) //this is the actual value that will be placed inside the textbox
{
//Parse out the ID suffix in brackets and place only the account name itself into the textbox for the name
$accountMaintenanceWrapper.find('#MasterAccountId').val(i.substring(i.indexOf('(')+1,i.indexOf(')')));
return i.substring(0,i.indexOf('('));
}
}
);
$accountMaintenanceWrapper.find("#MasterAccount").result(SetupCallBackForMasterAccount).next().click(function() {
$(this).prev().search();
});
//When the auto complete textbox is empty, delete the key code from the text
$accountMaintenanceWrapper.find("#MasterAccount").bind('keyup',function() {
if ($(this).val() == '')
{
$accountMaintenanceWrapper.find('#MasterAccountId').val('')
}
});
//This function parses the matched auto complete value's suffix key (in between parenthesis)
function SetupCallBackForMasterAccount(event, data, formatted) {
$('#MasterAccountId').val( !data ? " " : formatted.substring(formatted.indexOf('(')+1,formatted.indexOf(')')));
}
Here is the C# code controller action:
[AcceptVerbs(HttpVerbs.Get)]
public string GetMatchingAgentsWithIdSuffix(string q)
{
if (String.IsNullOrEmpty(q))
return null;
var sb = new StringBuilder();
foreach (AccountNameIdDTO dto in _accountRepository.SearchForAccountsStartingWithNameSuffixKey(q))
{
if ((Repository.Get(dto.Id) as Agency) != null)
sb.AppendLine(dto.Name + "(" + dto.Id + ")");
}
return sb.ToString();
}
Couple of pointers:
- $accountMaintenanceWrapper - I declare this variable as I am referencing this container several times and to speed performance let jQuery find it and set the reference only once.
- MasterAccountId - this is the readonly textbox that will contain the value of the unique ID
- MasterAccount - this is the textbox where the user enters the name of the account
- minChars:3 - Starts the search after/on three characters
- selectFirst : true - if the user does not click on the name and simply tabs out will select the first one
No comments:
Post a Comment