SiSharp
SiSharp

Reputation: 121

Mvc5 Select2 load results via ajax based on searchTerm

I’m trying to use Select2 and load data with ajax based on search term. I looked so many examples, but I just can’t figure it out what am I missing.

I added select2.css and select.js and included them in the layout view.

@Styles.Render("~/Content/css")
    <link type="text/css" rel="Stylesheet" href="@Url.Content("~/Content/select2.css")" />
@Scripts.Render("~/bundles/jquery")
    <script type="text/javascript" src="../../Scripts/select2.min.js"></script>

This is in the view which displays textbox for search:

// Not sure what here should be also.
<input id="productSelect" style="width:200px" />


@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script type="text/javascript">
$(function () {
        $('#productSelect).select2({
            placeholder: 'Select a product',
            minimumInputLength: 1,
            ajax: {
                url: '@Url.Action("SearchProducts", "Product")',
                dataType: 'json',
                data: function (term, page) {
                    return {
                        searchTerm: term
                    };
                },
                results: function (data, page) {
                    return { results: data };
                }
            }
        });

    });
</script>
}

This is the method in the controller:

public JsonResult SearchProducts(string searchTerm)
        {
            var products = Db.Products.Where(p => p.Name.Contains(searchTerm));
            var result = products.Select(p => new { id = p.Id, text = p.Name });
            return Json(result, JsonRequestBehavior.AllowGet);
        }

The textbox is not showing data or searching anything. Can someone, please, explain how it should be done correctly? Thank you.

Upvotes: 1

Views: 196

Answers (1)

Soma Mbadiwe
Soma Mbadiwe

Reputation: 1674

select2 dropdowns work like search box too. So, typically you do not need <input id="productSelect" style="width:200px" /> as input. Instead, do these:

  1. Create the <select> tag

<select id="productSelect">
    <option value="" selected="selected">Search for product...</option>
</select>

  1. Set up the script

$("#productSelect").select2({
  ajax: {
    url: '@Url.Action("SearchProducts", "Product")',
    dataType: 'json',
    delay: 250,
    data: function (term) {
      return {
        searchTerm: term, // search term
      };
    },
    processResults: function (data) {
      
      return {
        results: data
      };
    },
    cache: true
  },
  minimumInputLength: 1,
});

  1. If you need the data to be loaded in batches, giving an illusion of infinite scrolling, then modify your controller to return a JSON data with two parameters: the batch (I called it Items) and total count (I called it TotalCount). Your script will then look like this:

$("#productSelect").select2({
  ajax: {
    url: '@Url.Action("SearchProducts", "Product")',
    dataType: 'json',
    delay: 250,
    data: function (params) {
      params.page = params.page || 1;
      return {
        searchTerm: params.term, // search term
        page: params.page, // 1-based page indexing
      };
    },
    processResults: function (data, params) {
      
      params.page = params.page || 1;
      return {
          results: data.Items,
          pagination: {
              more: (params.page * 30) < data.TotalCount
          }
      };
    },
    cache: true
  },
  minimumInputLength: 1,
});

Upvotes: 1

Related Questions