Search code examples
ajaxautocompleteasp.net-core-mvc

Trying to display autocomplete results - ASP.NET Core MVC


I have an API that I call and it calls the method that returns the data to the Ajax call. All good. What I see in my text box is just a bunch of objects. Here is all my code. I know I am soo close.

ASP.NET Core MVC - this is working to GET the data.

Some of the view:

<tr>
    <td class="pe-1 col-md-1">
         <input type="text" id="search" placeholder="id or name" class="form-control w-search ui-autocomplete" autocomplete="on" />                                        
    </td>
    <td class="col-md-6">
        <input type="button" value="Search" id="searchButton" class="btn btn-primary2 w-auto ms-0" />
    </td>                                   
</tr>

AJAX call:

$(document).ready(function () {
    $("#search").autocomplete({
        source: function (request, response) {
            $.ajax({
                url: '/api/AutoComplete/search',
                headers: {
                    "RequestVerificationToken":
                        $('input[name="__RequestVerificationToken"]').val()
                },
                // data: { "term": request.term },
                data: JSON.stringify(request.term),
                datatype: 'json',
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    // response($.map(data, function (item) {
                    //     return {
                    //         label: item.name,
                    //         value: item.id
                    //     };
                    // }));
                     $('#search').val(data);  //NEED TO DISPLAY IT HERE
                    debugger;
                },
                error: function (xhr, textStatus, error) {
                    alert(xhr.statusText);
                },
                failure: function (response) {
                    alert("failure " + response.responseText);
                }
            });
        },
        select: function (e, i) {
            alert(e);
            alert(i);
        },
        minLength: 1,
        DelayNode: 800
    });
});`

API:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MIParticipation.Models;
using MIParticipation.Models.ViewModel;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MIParticipation
{
    [Route("api/AutoComplete")]
    [ApiController]
    public class AutoCompleteAPIController : ControllerBase
    {
        private MiparticipationContext db = new MiparticipationContext();

        [Produces("application/json")]
        [HttpGet("search")]
        [Route("home/search")]
        public async Task<IActionResult> Search()
        {
            try
            {
                string term = HttpContext.Request.Query["term"].ToString();

                Task<List<SearchListResults>> results = null;
                int intResult;
                bool isNAIC = int.TryParse(term, out intResult);
                
                if (isNAIC == true)
                {
                    results = db.SearchAutoComplete(term);                    
                }
                else
                {
                    results = db.SearchAutoComplete(term);
                }
                    
                return Ok(await results);
            }
            catch (Exception ex)
            {
                return BadRequest();
            }
        }
    }
}

Database method:

public async Task<List<SearchListResults>> SearchAutoComplete(string _searchString)
{
    var searchString = new SqlParameter("@SearchValue", _searchString);

    List<SearchListResults> results = new List<SearchListResults>();
    SearchListResults result = null;
           
    try
    {            
        var builder = WebApplication.CreateBuilder();
        var connectionString = builder.Configuration.GetConnectionString("MiParticipationConnection");

        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            SqlCommand cmd = new SqlCommand()
            {
                CommandText = "spGetFilteredCompanyList",
                CommandType = System.Data.CommandType.StoredProcedure
            };

            SqlParameter param1 = new SqlParameter
            {
                ParameterName = "@SearchValue", 
                SqlDbType = SqlDbType.VarChar, 
                Value = _searchString, 
                Direction = ParameterDirection.Input 
            };

            cmd.Parameters.Add(param1);
            cmd.Connection = conn;

            conn.Open();

            SqlDataReader rdr = cmd.ExecuteReader();
            
            if (rdr.HasRows)
            {
                while (rdr.Read())
                {
                    SearchListResults list = new SearchListResults()
                    {
                        id= rdr["id"].ToString(),
                        name = rdr["name"].ToString()
                    };
                    results.Add(list);                        
                }                  
            }                                        
        }
    }
    catch (System.Exception ex)
    {
        NLog.Logger _logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
        _logger.Error("Exception " + "InnerException " + ex.InnerException + "Message " + ex.Message + "StackTrace:" + ex.StackTrace + " Method that failed: " + MethodBase.GetCurrentMethod());
    }
    
    return await Task.FromResult(results);        
}

Model class:

using System.ComponentModel.DataAnnotations.Schema;

namespace MIParticipation.Models.ViewModel
{
    public class SearchListResults
    {
        public string naic { get; set; }
        public string name { get; set; }
    }
}

I checked the results from the db method and the data looks good list of (id, name). I can display both concatenated but I really only need the id after they make a selection. Sorry for my newbieness. I hope I posted enough. I want the list to show in the textbox or something else.

Thanks in advance, M


Solution

  • A few steps needed.

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
    
    <h2>@ViewData["Title"]</h2>
    
    <div class="row">
        <div class="col-md-6">
            <label for="search">Search:</label>
            <input type="text" id="search" name="search" class="form-control">
        </div>
    </div>
    
    <script>
        $(document).ready(function () {
            $("#search").autocomplete({
                source: function (request, response) {
                    $.ajax({
                        url: '/api/AutoComplete/Search',
                        data: { term: request.term },
                        dataType: 'json',
                        success: function (data) {
                            response($.map(data, function (item) {
                                return {
                                    label: item.name,
                                    value: item.id    
                                };
                            }));
                        },
                        error: function (xhr, textStatus, errorThrown) {
                            console.error('Error in fetching autocomplete data: ', textStatus);
                        }
                    });
                },
            });
        });
    </script>
    

    enter image description here