Summary
I have been using/learning MVC for a while now and I struggled to attain a neat solution to having int userid
primary key field in a database with a separate username field. In my instance, I autocalculate the username from the first and last name.
I wanted standard code no matter what the foreign key field for the user was called.
This code should allow you to have integer primary key fields in your database whilst using English autocompletes on form fields, and keeping all code standard, and allowing users to enter the first name last name or username of the user required.
So scenarios where you have foreign fields such as those below can be int
fields in your database and the user only sees the display name. (e.g.: Mark Anthony : AnthoMa)
AssignedTo
OwnerId
AuthorId
ApproverId
Summary of Files and Code Snippets
The jquery file provides the autocomplete functionality backed up with the autocomplete support method in the account controller.
The view code has two fields, one a text field for user friendly usernames and a hidden data bound field.
This is all fine on create, but where the code is useful is on the edit record. The jquery initialiseValues
function will find the hidden fields and populate the matching usernames into the textbox
.
The data-property-name attribute is used to pair up sets of inputs.
Account Controller
AutoComplete Function within the account controller:
public JsonResult UserAutoComplete(string term)
{
using (DBContext db = new DBContext())
{
List<Account> users = db.Accounts
.Where(x => ((x.UserName.Contains(term)) ||
(x.FirstName.Contains(term)) ||
(x.LastName.Contains(term))))
.ToList();
return Json(users.Select(x => new { id = x.AccountId,
value = x.FirstName + " " + x.LastName + ": " + x.UserName,
label = x.FirstName + " " + x.LastName + ": " + x.UserName }),
JsonRequestBehavior.AllowGet);
}
}
Helper function within the account controller:
?public string GetDisplayNameFromId(int id)
{
using (DBContext db = new DbContext())
{
Account acc = db.Accounts.Find(id);
return acc.FirstName + " " + acc.LastName + ": " + acc.UserName;
}
}
ViewCode
Razor Code for the Create and Edit Views:
@Html.TextBox("Username",null,new{@class="form-control username-autocomplete",
data_property_name="AssignedTo"})
@Html.HiddenFor(model=>model.Item.AssignedTo,new{@class="hidden-accountid",
data_property_name="AssignedTo"})
JQuery
File called UserAutoComplete
:
$(document).ready(function () {
initialiseValues();
$('.username-autocomplete').autocomplete({
minLength: 1,
source: "/Account/UserAutoComplete",
select: function (event, ui) {
var propertyName = $(this).attr('data-property-name').valueOf();
$('.hidden-accountid[data-property-name=' + propertyName + ']').val(ui.item.id)
}
});
$('.username-autocomplete').attr('autocomplete', 'on');
});
function initialiseValues()
{
$('.hidden-accountid').each(function (index, element) {
var displayName;
var id = $(this).val();
$.get("/Account/GetDisplayNameFromId?id=" + id, null, function (data, status) {
displayName = data;
});
var propertyName = $(this).attr("data-property-name").valueOf();
var selectStr = '.username-autocomplete[data-property-name="' + propertyName + '"]';
$(selectStr).val(displayName);
});
}