Sam khan
Sam khan

Reputation: 220

Select2 auto complete search is not showing data asp.net mvc 5

When I type or search anything in select2 textbox so it shows searching and it does not show the data from database. I had put breakpoint on searchProdauto and when compiler come on it,

searchData action search data successfully but it does not show in select2 textbox..

Here is my Home Controller

 // GET: /Common/Home/
    public ActionResult Index()
    {
        return View();
    }
    [HttpGet]
    public JsonResult searchProdauto(string q)
    {
        var searchData = rep.GetAll().Where(x => x.ProductName.StartsWith(q, 

StringComparison.InvariantCultureIgnoreCase)).Select(y => 
  y.ProductName).ToList();
        return Json(searchData, JsonRequestBehavior.AllowGet);
    }

Index.cshtml view code

@using Medi.Modals
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<script src="~/Scripts/jquery-2.1.4.min.js"></script>
<script src="~/Scripts/metro.min.js"></script>
<script   src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<script src="~/Scripts/jquery-ui-1.10.4.custom.min.js"></script>
<link href="~/Content/metro.css" rel="stylesheet" />
<link href="~/Content/jquery-ui-1.10.4.custom.min.css" rel="stylesheet" />
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<br />
<div class="cell auto-size padding20" style="margin-top:1rem;">
<h2>Select2 Examples</h2>
<h3>Basic</h3>
<select class="js-data-example-ajax">
    <option value="3620194" selected="selected">select2/select2</option>
</select>
<br />
</div>
<script type="text/javascript">

    $(".js-data-example-ajax").select2({
        ajax: {

            url: '@Url.Action("searchProdauto","Home")',
            dataType: 'json',
            delay: 250,
            data: function (params) {
                return {
                    q: params.term, // search term
                    page: params.page
                };
            },
            processResults: function (data, page) {
                // parse the results into the format expected by Select2.
                // since we are using custom formatting functions we do not need to
                // alter the remote JSON data
                return {
                    results: data.items
                };
            },
            cache: true
        },
        escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
        minimumInputLength: 1,

    });

</script>

Upvotes: 2

Views: 3351

Answers (1)

LeftyX
LeftyX

Reputation: 35597

You have to change the way you process the result according to the definition of your json objected returned by your controller:

public JsonResult searchProdauto(string q)
{
    var searchData = rep.GetAll().Where(x => x.ProductName.StartsWith(q,StringComparison.InvariantCultureIgnoreCase)).Select(y => y.ProductName).ToList();
    return Json(searchData, JsonRequestBehavior.AllowGet);
}

It seems that you're trying to return a list of ProductName. Select2 needs and id and a text.

You could change your code to return a json object with an id:

var searchData = rep.GetAll().Where(x => x.ProductName.StartsWith(q, StringComparison.InvariantCultureIgnoreCase))
    .Select(f => new
   {
    ProductName = f.ProductName,
    ProductId = f.ProductId
   })
.ToList();

return Json(searchData, JsonRequestBehavior.AllowGet);

then you have to define a rule to map your properties to Select2 properties:

processResults: function (data, search) {
        return {
            results: $.map(data, function (item) {
                return {
                  id: item.ProductId ,
                  text: item.ProductName,
                }
            });
        };
}

I guess you have to change select2 data member as well as you're not passing a page to your controller:

data: function (params) {
        return {
           q: params.term, // search term
           // page: params.page
        };
},

and you might have to add

templateResult: function (item) {
    if (item.loading) return item.text;
    return item.text;
},

Your final code to create a select2 element should look something like this:

$(".js-data-example-ajax").select2({
        ajax: {
            url: '@Url.Action("searchProdauto","Home")',
            dataType: 'json',
            delay: 250,
            data: function (params) {
                return {
                    q: params.term, 
                    // page: params.page
                };
            },
            processResults: function (data, search) {
                return {
                    results: $.map(data, function (item) {
                      return {
                        id: item.ProductId ,
                        text: item.ProductName,
                      }
                   });
               };
            },
            cache: true
        },
        templateResult: function (item) {
          if (item.loading) return item.text;
          return item.text;
        },      
        escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
        minimumInputLength: 1,

});

if you want to access the data of your selection you can use:

var data $('.js-example-data-ajax').select2('data');

it should contain an array of values passed in

templateResult: function (item) { }

so if you want to fetch ProductName of the selected item you should be able to do something like this:

$('.js-example-data-ajax').select2('data')[0].ProductName;

Upvotes: 4

Related Questions