0

I apologize this is sort of a repeat, however even after looking at several other questions on the topic, I'm still not able to get mine working.

I want to use a JQuery AutoComplete widget in my form to select from 30K+ records in a database. I believe my issues stems around the source of the .autocomplete function.

HTML + JS

@using (Html.BeginForm())
{
    @Html.LabelFor(model => model.Name)
    @Html.TextBoxFor(model =>model.Name, new { id="Search"})
}
<script type="text/javascript">
    $('#Search').autocomplete({
        source: '@Url.Action("GetVendors", "TestAutoComplete")',
        minLength: 3
    });
</script>

Controller Action

[HttpGet]
public JsonResult GetVendors(string Search)
{
  return Json(DB.VendorLookUp(Search), JsonRequestBehavior.AllowGet);
}

I know my DB.VendorLookUp method works (I've tested it separately) and I have a breakpoint inside the GetVendors method which doesn't get hit.

In the console I get this error:

GET http://localhost:50848/TestAutoComplete/GetVendors?term=mic 500 (Internal Server Error)

(where 'mic' is the search I attempted). I assume at least part of the problem is that my controller method is excepting string "Search", when the JS is trying to GET "term".

Thanks in advance for your assistance.

EDIT: Things I've already tried:

  • Changing parameter "Search" to "term" in my controller action
  • Not having any parameters in my controller action
  • Updating the @Url.Action() to pass along the value to:
    • source: '@Url.Action("GetVendors", "TestAutoComplete", new {Search= $('#VendorSearch').val() })'
    • but get the error
    • Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.

UPDATE: Error Messages Console Error

Network Error

UPDATE:

Thanks to comment suggestion, looking at the error via Network -> Inspect Response gave me a meaningful error. I was trying to catch the js call anyway I could so had 2 controller actions - one with a parameter, and one with no parameters. This was confusing the code. I removed the action with no parameters and now the controller action is behaving properly and DB.VendorLookUp is returning a List of Vendor_VMs (which the controller properly converts to a JSON object).

However, the results are not returning correctly - see image 3 below. The options are not in a dropdown and are not displaying any values.

  1. How do I update the cshtml / js to pass the Name along to the input form?
  2. How do I make the values appear in the appropriate dropdown manner?

AutoComplete Results not showing

Roman Pokrovskij
  • 9,449
  • 21
  • 87
  • 142
swallis1
  • 99
  • 1
  • 13
  • Change the method to `public JsonResult GetVendors(string term)` –  Feb 27 '17 at 20:41
  • I already tried that. Still get the error: `GET http://localhost:50848/TestAutoComplete/GetVendors?term=mic 500 (Internal Server Error)` when my controller action reads: `[HttpGet] public JsonResult GetVendors(string term) { return Json(DB.VendorLookUp(term), JsonRequestBehavior.AllowGet); }` – swallis1 Feb 27 '17 at 21:03
  • Then your `VendorLookUp()` method is throwing an exception. Use you browser tools (the Network tab to inspect the result which will include the details of the error) –  Feb 27 '17 at 21:08
  • What does the code for ``DB.VendorLookUp`` look like? – Rick Burns Feb 27 '17 at 21:12
  • See error messages above. Network and console are throwing the same error. I don't think the problem is on the controller side b/c the break point isn't getting hit. (Thus, the DB.VendorLookup is also not being hit - also have another break point in that method). – swallis1 Feb 27 '17 at 21:30
  • @swallis1 - click on the highlighted item and then inspect the response tab –  Feb 27 '17 at 21:33
  • And what does `VendorLookUp()` return (is it `IEnumerable`). –  Feb 27 '17 at 21:35
  • Your method need to return `IEnumerable` which are the values that will be displayed. Or if your need to return other properties - e.g. an `ID` that you might set in a hidden input, then refer [this answer](http://stackoverflow.com/questions/39217750/mvc-autocomplete-editorfor-while-using-html-begincollectionitem/39284188#39284188) - in any case return only the properties you need. –  Feb 27 '17 at 22:22

1 Answers1

0

This works: 1) Create an action in your controller and set the RouteConfig to start this action

public class HomeController : Controller
{
    public ActionResult Index20()
    {
        MyViewModel m = new MyViewModel();
        return View(m);
    }

Create a view without any type of master page

Add this view model:

public class MyViewModel
{
    public string SourceCaseNumber { get; set; }
}

Go to Manage Nuget Packages or PM Console and add to MVC 5 project - Typeahead.js for MVC 5 Models by Tim Wilson

Change the namespace for the added HtmlHelpers.cs to System.Web.Mvc.Html and rebuild

Add this class:

public class CasesNorm
{
    public string SCN { get; set; }
}

Add these methods to your controller:

private List<Autocomplete> _AutocompleteSourceCaseNumber(string query)
    {
        List<Autocomplete> sourceCaseNumbers = new List<Autocomplete>();
        try
        {
            //You will goto your Database for CasesNorm, but if will doit shorthand here

            //var results = db.CasesNorms.Where(p => p.SourceCaseNumber.Contains(query)).
            //    GroupBy(item => new { SCN = item.SourceCaseNumber }).
            //    Select(group => new { SCN = group.Key.SCN }).
            //    OrderBy(item => item.SCN).
            //    Take(10).ToList();   //take 10 is important

            CasesNorm c1 = new CasesNorm { SCN = "11111111"};
            CasesNorm c2 = new CasesNorm { SCN = "22222222"};
            IList<CasesNorm> aList = new List<CasesNorm>();
            aList.Add(c1);
            aList.Add(c2);
            var results = aList;

            foreach (var r in results)
            {
                // create objects
                Autocomplete sourceCaseNumber = new Autocomplete();

                sourceCaseNumber.Name = string.Format("{0}", r.SCN);
                sourceCaseNumber.Id = Int32.Parse(r.SCN);
                sourceCaseNumbers.Add(sourceCaseNumber);
            }
        }
        catch (EntityCommandExecutionException eceex)
        {
            if (eceex.InnerException != null)
            {
                throw eceex.InnerException;
            }
            throw;
        }
        catch
        {
            throw;
        }
        return sourceCaseNumbers;
    }

    public ActionResult AutocompleteSourceCaseNumber(string query)
    {
        return Json(_AutocompleteSourceCaseNumber(query), JsonRequestBehavior.AllowGet);
    }

     throw;
    }
    catch
    {
        throw;
    }
    return sourceCaseNumbers;
}

public ActionResult AutocompleteSourceCaseNumber(string query)
{
    return Json(_AutocompleteSourceCaseNumber(query), JsonRequestBehavior.AllowGet);
}

credit goes to http://timdwilson.github.io/typeahead-mvc-model/

kblau
  • 2,094
  • 1
  • 8
  • 20