How to load jquery autocomplete dropdown box from an external WEB API

Jose Daniel Navarro Brito 61 Reputation points
2025-02-06T10:32:43.52+00:00

Good day everybody:

I have an external web api which returns a label, value records needed for a client application

app.MapGet("/AsyncAutocompleteErf/{search}", async (IErvenRepository request, string search) =>
{
    var data = await request.GetSearchedErfNumberAsync(search);
    if (data == null)
        return Results.NotFound("Sorry, there are not records");
    return Results.Ok(data);
}).WithName("AsyncAutocompleteErf");


The method returns the following JSON array

[
  {
    "label": "15209  Gugulethu Infill Housing ",
    "value": "1"
  },
  {
    "label": "15211  Edward Avenue",
    "value": "3"
  }
]

In the client application , I have a method that call the above REST WEB Api

 [HttpGet]

 public async Task<JsonResult> AutoComplete(string param)
 {
     {

         var httpClient = _httpClientFactory.CreateClient("HousingWebAPI");
         using (var response = await httpClient.GetAsync("AsyncAutocompleteErf/" + param))
         {
             if (response.IsSuccessStatusCode)
             {
                 var content = await response.Content.ReadAsStringAsync();
                 var apiResponseBody = JsonConvert.DeserializeObject<IEnumerable<AutoSearchViewModel>>(content);
                 return Json(apiResponseBody);
             }
         }
     }
     return null;
 }

Up to this point everything is fine. The script that fires up the Jquery Autocomplete is as follows:

<script>
    $( function() {        
    $("#search" ).autocomplete({
    source: function( request, response ) {
    $.ajax( {
    url: "Erf/AutoComplete",
    dataType: "json",
    type:"GET",
     data: {param:request.term},
    success: function( data ) {
    response($.map(data, function (item) {

    return item;            

    }));


    },
    error: function (response)
    {
    toastr.error(response.responseText);
    }
    ,
    failure: function (response) 
    {
    toastr.error(response.responseText);
    }

    } );
    },
    minLength: 2
    

    });
    } );

</script>

The browser developer tools ( debugger) confirms that the response is [{"label":"15211 Edward Avenue","value":"3"}] when the user types 11 in the search textbox which is the expected value.

The issue is that the label values which in this case is "15211 Edward Avenue "isn't displayed in the text box

<div id="searchBar" tabindex="-1">
    <input type="text" name="search" id="search" class="ui-autocomplete" placeholder="Search for Blocks" tabindex="-1">
    <ul class="ui-menu" id="searchResults"></ul>
</div>

The above HTML mark up is embedded in a modal pop up dialog. All the required references for making the autocomplete works are in the _Layout.cshtml and not in the pop up dialog ( not sure whether this is the reason why nothing is displayed).

The scripts references I have in the _Layout.cshtml page are:

<script src="https://code.jquery.com/jquery-3.7.1.js"></script>

<script src="https://code.jquery.com/ui/1.14.1/jquery-ui.js"></script>

<partial name="~/Views/UIComponents/_ModalForm.cshtml" />

Any ideas about what is going wrong?

Regards

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,772 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,590 questions
JavaScript API
JavaScript API
An Office service that supports add-ins to interact with objects in Office client applications.
1,038 questions
{count} votes

4 answers

Sort by: Most helpful
  1. AgaveJoe 29,776 Reputation points
    2025-02-06T13:49:58.57+00:00

    From my perceptive, the logic/design is incomplete. The AJAX response is an array of objects. The jQuery map function should drill into the objects using standard dot syntax. Your current design copies the object array to another object array.

    https://api.jquery.com/jQuery.map/

    I'm not a jQuery autocomplete expert and this is not a jQuery autocomplete support forum. The official jQuery autocomplete examples illustrate how to return a list of strings.

    https://jqueryui.com/autocomplete/#remote-jsonp

    Following the example is a mock up that return a comma separated string; label,value.

    Gugulethu Infill Housing ,1
    Edward Avenue,3
    
             const objectArray = [
              {
                "label": "15209  Gugulethu Infill Housing ",
                "value": "1"
              },
              {
                "label": "15211  Edward Avenue",
                "value": "3"
              }
            ];
    
            var list =  $.map(objectArray, function (o) {
                 console.log( o.label + ',' + o.value);
                 return o.label + ',' + o.value;
            });
    
    
    

    If you need to populate HTML with the label text and value then you'll need to show us the expected dynamic HTML results.

    0 comments No comments

  2. Ping Ni-MSFT 4,815 Reputation points Microsoft Vendor
    2025-02-07T08:37:56.63+00:00

    Hi Jose Daniel Navarro Brito,

    Add class ui-front in modal-body like below:

    <!-- Modal -->
    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
       <!--Add class ui-front in modal-body here -->
                <div class="modal-body ui-front">
                    <div id="searchBar" tabindex="-1">
                        <input type="text" name="search" id="search" class="ui-autocomplete" placeholder="Search for Blocks" tabindex="-1">
                        <ul class="ui-menu" id="searchResults"></ul>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Rena

    0 comments No comments

  3. Bruce (SqlWork.com) 71,101 Reputation points
    2025-02-07T17:40:15.08+00:00

    you appear to be using both bootstrap and jQuery-UI. It is always troublesome to combine these two frameworks, as they have conflicting methods and CSS. see:

    https://stackoverflow.com/questions/9048214/can-i-use-twitter-bootstrap-and-jquery-ui-at-the-same-time

    I'd remove the jQuery-UI autocomplete and pick a bootstrap compatible autocomplete

    https://github.com/twitter/typeahead.js

    https://github.com/iqbalfn/bootstrap-autocomplete

    note: I use react and use a react bootstrap autocomplete and can not recommend a jQuery version.

    0 comments No comments

  4. MohaNed Ghawar 75 Reputation points
    2025-02-06T14:59:11.9566667+00:00
    1. First, update your _Layout.cshtml to ensure proper script loading order:
         <!DOCTYPE html>
         <html>
         <head>
             <!-- Other head elements -->
             <link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
             <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
             <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
         </head>
      
    2. Update your modal partial view (_ModalForm.cshtml) with this structure:
         <div class="modal fade" id="searchModal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
             <div class="modal-dialog" role="document">
                 <div class="modal-content">
                     <div class="modal-header">
                         <h5 class="modal-title" id="searchModalLabel">Search</h5>
                         <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                             <span aria-hidden="true">&times;</span>
                         </button>
                     </div>
                     <div class="modal-body">
                         <div id="searchBar">
                             <input type="text" name="search" id="search" class="form-control" placeholder="Search for Blocks">
                         </div>
                     </div>
                 </div>
             </div>
         </div>
      
    3. Replace your JavaScript code with this updated version:
         $(document).ready(function() {
             // Initialize autocomplete when modal opens
             $('#searchModal').on('shown.bs.modal', function () {
                 $("#search").autocomplete({
                     source: function(request, response) {
                         $.ajax({
                             url: "/Erf/AutoComplete",
                             dataType: "json",
                             type: "GET",
                             data: { param: request.term },
                             success: function(data) {
                                 // Direct mapping without $.map since your data is already in correct format
                                 response(data);
                             },
                             error: function(xhr, status, error) {
                                 toastr.error("Error: " + error);
                             }
                         });
                     },
                     minLength: 2,
                     select: function(event, ui) {
                         if (ui.item) {
                             $("#search").val(ui.item.label);
                             // Optional: Do something with ui.item.value
                             return false;
                         }
                     }
                 }).autocomplete("instance")._renderItem = function(ul, item) {
                     // Custom rendering of dropdown items
                     return $("<li>")
                         .append("<div>" + item.label + "</div>")
                         .appendTo(ul);
                 };
             });
             // Clear input when modal closes
             $('#searchModal').on('hidden.bs.modal', function () {
                 $("#search").val('');
             });
         });
      
    4. Add these CSS styles:
    .ui-autocomplete {
        z-index: 2000; /* Ensure dropdown appears above modal */
        max-height: 200px;
        overflow-y: auto;
        overflow-x: hidden;
    }
    
    .ui-menu-item {
        padding: 5px 10px;
        cursor: pointer;
    }
    
    .ui-menu-item:hover {
        background-color: #f8f9fa;
    }
    
    #searchBar {
        position: relative;
        width: 100%;
    }
    
    #search {
        width: 100%;
        padding: 8px;
        border: 1px solid #ddd;
        border-radius: 4px;
    }
    
    

    Additional tips:

    1. Make sure your AutoComplete action in the controller is returning the exact format:
         public class AutoSearchViewModel
         {
             public string label { get; set; }
             public string value { get; set; }
         }
      
    2. If you're using Bootstrap modal, make sure you have the Bootstrap JS included:
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.