I have implemented the Ajax Autocomplete feature in my application using a web service file that querys my database and it works great. One problem I am having is allowing the user to see the item's name, as that's what they are typing in the textbox, but when they select it, it saves the item's ID number instead of the actual name. I want it to behave much like a dropdown list, where I can specify what is seen and entered vs. what is actually saved in the database (in this case, the product ID instead of it's name.)
I have this text box in my view, along with the script:
<script type="text/javascript">
Sys.Application.add_init(function() {
$create(
AjaxControlToolkit.AutoCompleteBehavior, {
serviceMethod: 'ProductSearch',
servicePath: '/ProductService.asmx',
minimumPrefixLength: 1,
completionSetCount: 10
},
null,
null,
$get('ProductID'))
});
</script>
<p>
<label for="ProductID">Product:</label>
<%= Html.TextBox("ProductID", Model.Products)%>
&开发者_如何学Pythonlt;%= Html.ValidationMessage("ProductID", "*")%>
</p>
Here's what is in my asmx file:
public class ProductService : System.Web.Services.WebService
{
[WebMethod]
public string[] ProductSearch(string prefixText, int count)
{
MyDataContext db = new MyDataContext();
string[] products = (from product in db.Products
where product.ProductName.StartsWith(prefixText)
select product.ProductName).Take(count).ToArray();
return products;
}
}
Can anyone help me figure this out? I'm using this so they can just start typing instead of having a dropdown list that's a mile long...
the autocomplete control will post a json object to "servicePath/serviceMethod" so first, set the servicePath
to your controller and the serviceMethod
option to your action name.
then define this class:
public class AutoCompleteRequest
{
public string PrefixText { get; set; }
public int Count { get; set; }
}
because thats the json object the autocomplete control posts to your controller.
then define a JsonModelBinder:
public class JsonBinderAttribute : CustomModelBinderAttribute
{
public override IModelBinder GetBinder()
{
return new JsonModelBinder();
}
public class JsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
try
{
var inputStream = controllerContext.HttpContext.Request.InputStream;
using (var sr = new StreamReader(inputStream))
{
var json = sr.ReadToEnd();
return JsonConvert.DeserializeObject(json, bindingContext.ModelType);
}
}
catch
{
return null;
}
}
}
}
this one is using Json.Net as deserializer.
then define your action like this:
public virtual JsonResult SearchA([JsonBinder]AutoCompleteRequest post)
{
var data = repository.Query<A>()
.Where(s => s.Name.StartsWith(post.PrefixText))
.Take(post.Count)
.Select(s => s.Name)
.ToArray();
return Json(data);
}
note how i use the JsonBinderAttribute on the AutoCompleteRequest parameter and how a Json array of strings is returned.
Edit
i did a follow up blog post here: http://devcarl.posterous.com/how-to-use-ajax-library-4-autocomplete-with-a
Although this doesn't answer your question directly have you thought about using the Jquery autocomplete control?
From my experience it seems more flexible and you could link it up with your existing service and have more control over the data that is returned as well. Here the link if it helps.
精彩评论