Autocompleting cascading dropdowns

Written by  on July 3, 2011 

 

Starting point for this post is source code for last one, available on bitbucket.

I want to replace dropdown list with jQuery autocomplete, like in this example. There are two reasons for this:

  • When there is very large number of records to choose from, then standard dropdown list is not very user friendly
  • When user is entering name of item, besides autocompleting from known items, we can implement addition of new item if item user needs to enter is not present in codebook. This will be done in next post.

For start, I will copy example from jQuery demo, and add textbox in which I will implement this functionality.

image

I have added this code to Index.chtml, which is label for manufacturer, hidden field with id for chosen value from dropdown, and textbox for autocomplete. I have added three attributes for this textbox:
- autocomplete-for is target (hidden field) into which I want to place chosen value
- from-url is address where I will get items for autocomplete
- parent is field for cascading functionality (this will be optional)

Client side code for autocomplete is based on jsonp example from jQuery ui demo:

image

I have added this init function to document ready event. What is happening here is simple: for each input element that has “autocomplete-for” attribute, jQuery autocomplete is added, with custom function as data provider. This function is using ajax to request data for dropdown from from-url specified in view. Parameters are MaxItems (amount of items to show in autocomplete), ParentFilterId (selected value of parent field – for cascading support) and NameStartsWith, which is text entered into dropdown which is autocompleted.

Success function maps “items” collection in response to label, value and id. label and value are automatically used by autocomplete plugin to show label for item in dropdown and to set textbox value when item is selected, and I added id to set hidden field in select event.

To make this work, there is one thing left: controller action which will return items. As you can see in first screenshot, I decided to use Manufacturer controller and action named Autocomplete.

To make parameter passing easier, I have created model for data passed in request:

image

I will receive this object as parameter in my action.

This is how implementation of autocomplete action looks:

image

This is fairly simple – query is filtered by name for NameStartsWith parameter, and I used ToLower method of string, to compare case insensitive, as StartsWith with string comparison options parameter is not supported in linq to entities.

If request contains parent filter id or max items number, then these are taken into account, and response is formed as collection of items with Text, Value and Id properties, which are used in success function of ajax request.

Time to see how it works:

imageimageimage

As this is working nicely, time for little makeup, as I want this more reusable, and not having to remember html attributes that need to be used. So, that smells like html helper:

image

Actually, it is two helpers – one for cascading case, and one for “normal”. It is the same code as in cshtml view, but creating hidden and text field in one method, and when I add comments here (removed to make screenshot smaller), I will have nice intellisense to use this function whenever I need, only having to copy and adjust controller action, which also can be made pretty generic.

 

image

This is how autocomplete is used now. I’m ready to call this a day, and source code from this post is in this changeset on bitbucket.

Category : ASP.NET MVCjQueryProgramming

Tags :

  • Muhammad Khan

    Hey Goran,

    Has the source for this moved somewhere? Bitbucket seems to give me an error.

    Thanks,
    Muhammad

  • obrad

    No, it is still on BitBucket, in a public repository.

    You need to be logged in to BitBucket to access it.

  • Scott

    Goran,

    I logged into BitBucket but still got an “Access Denied” error.

    Are you sure this repository is public?

    Or perhaps the links are wrong?

    I also tried searching for it in BitBucket, but could not find it.

    Can you please check all this?

    Thanks,
    Scott

  • obrad

    Please try now. If you still cannot access changeset url, try repository url: https://bitbucket.org/goranobradovic/cascading-dropdown-demo

    Regards

  • Scott

    Goran,

    Yes, I able to access it now.

    Thank you.

  • Scott

    Goran,

    One thing I had to change.

    On the second AutocompleteFor method (the simpler one), I had to remove TMasterProperty from the type list.

    That method was not available before making the change.

  • Steve

    Goran
    Thank you very much for this great post. I am using this code and got it to work great on my site for creating new entries. Is there a way to use the autocompletefor in Create view and it works great. I created a view to Edit an entry, but the autocompletefor won’t populate the TextBoxFor with the data from the database. I’d still like to use the autocompletefor on the edit page so that if someone wants to enter a different category, it will still autocomplete the textbox. Is there any way to do that?

  • obrad

    Hello Steve,

    Thank you for your comment.
    Without looking into your code/site, it is hard to tell what could be causing your problem. The dropdowns should work nevertheless is it create or edit, if the actions that return items to be put in dropdown are working and are correctly linked from your view. Try using some tool like Fiddler, or network tab in browser developer tools to check what does browser ask from server and if there are any errors. Maybe it is something related to path of action? Did you check if there are javascript errors? Is your site live somewhere where I can see it?

  • Slobodan

    Hvala Gorane, lep article. Pozdrav od Slobodana

  • obrad

    Hvala!

%d bloggers like this: