2

I am facing a problem in autocompleting the textbox vith hardcoded data, my json "Search" method does not fire i have been search a lot of code implement it into my project but did not get any success yet. i dont know where is the problem. kindly help me thankx in advance

Model:

  public class Locations
    {

        public int Id { get; set; }
        public string Name { get; set; }

    }

Controller:

public JsonResult Search(string query)
        {
            List<Locations> locations = new List<Locations>()
        {
            new Locations() {Id = 1, Name = "London"},
            new Locations() {Id = 2, Name = "Walles"},
            new Locations() {Id = 3, Name = "Birmingham"},
            new Locations() {Id = 4, Name = "Edinburgh"},
            new Locations() {Id = 5, Name = "Glasgow"},
            new Locations() {Id = 6, Name = "Liverpool"},
            new Locations() {Id = 7, Name = "Bristol"},
            new Locations() {Id = 8, Name = "Manchester"},
            new Locations() {Id = 9, Name = "NewCastle"},
            new Locations() {Id = 10, Name = "Leeds"},
            new Locations() {Id = 11, Name = "Sheffield"},
            new Locations() {Id = 12, Name = "Nottingham"},
            new Locations() {Id = 13, Name = "Cardif"},
            new Locations() {Id = 14, Name = "Cambridge"},
            new Locations() {Id = 15, Name = "Bradford"},
            new Locations() {Id = 16, Name = "Kingston Upon Hall"},
            new Locations() {Id = 17, Name = "Norwich"},
            new Locations() {Id = 18, Name = "Conventory"}

            };
            List<string> Loc;
            Loc = locations.Where(x => x.Name.StartsWith(query.ToLower())).Select(x => x.Name).ToList();
            return Json(Loc, JsonRequestBehavior.AllowGet);
        }

View:

@model IEnumerable<SearchBox.Models.Locations>
@using SearchBox.Models
@{
    ViewBag.Title = "Index";
}

<link href="~/Content/Autocomplete/jquery-ui.css" rel="stylesheet" />
<script src="~/Content/Autocomplete/jquery-ui.js"></script>
<link href="~/Content/Autocomplete/jquery-ui.theme.css" rel="stylesheet" />

<script type="text/javascript">
    $("#tags").autocomplete({
        source: '@Url.Action("Search")'
    });
</script>

    <input type="text" id="tags" />

4 Answers4

0

You need to make ajax request instead of passing just url in data source.

<link href="~/Content/jquery-ui.css" rel="stylesheet" />
<script src="~/Content/jquery-1.12.4.js"></script>
<script src="~/Content/jquery-ui.js"></script>

<input type="text" id="tags" />

<script type="text/javascript">
    $("#tags").autocomplete({
        source: function (request, response) {
            $.ajax({
                url: '@Url.Action("Search")',
                dataType: "jsonp",
                data: {
                    term: request.term
                },
                success: function (data) {
                    response($.map(data, function (item) {
                        return {
                            label: item.Name,
                            value: item.Id
                        };
                    }));
                }
            });
        },
        minLength: 2,
        select: function (event, ui) {

        }
    });
</script>

See how to use autocomplete with ajax request.

Amit Kumar
  • 5,888
  • 11
  • 47
  • 85
0

I have implemented this in my project. Please check if you can make use of it

<div class="tag_cover" style="margin-top:60px; margin-left:57px">
 <input type="text" style="width:300px; display:inline-block; border:transparent" class="tag_input brzero has-icon" id="SkillSet" list="json-datalist" placeholder="Employee name or Skills">
 <datalist id="json-datalist"></datalist>    
</div>

JQuery:

  $(".tag_input").keyup(function (e) {
        var type = $("input[name='search']:checked").val();
        if (type == "Name") {
            var sString = $("#SkillSet").val();
            if (sString == null || sString == "") {
                e.preventDefault();
            }
            else {
                $.ajax({
                    url: "@Url.Action("GetEmployeeNameByKeyword","Home")",
                    type: "POST",
                    data: { 'SearchedString': sString },
                    dataType: "json",
                    success: function (data) {
                        if (data == null || data == "") {
                            //alert("no skills found");
                        }
                        else {
                            var dataList = document.getElementById('json-datalist');
                            $(dataList).empty();
                            $.each(data, function (key, value) {
                                $(dataList).append($('<option>').text(value.UserNames.trim()).attr("value", value.UserId));
                            });
                        }
                    },
                    error: function () {
                        alert("failure");
                    }
                });
            }
        }
    }

Controller:

   public JsonResult GetEmployeeNameByKeyword(string SearchedString)
    {
        List<UserProfile> EmployeeNames = new List<UserProfile>();
        EmployeeNames = _db.UserProfiles.Where(i => i.UserNames.Contains(SearchedString)).ToList();
        return Json(EmployeeNames, JsonRequestBehavior.AllowGet);
    }
Naveen K N
  • 180
  • 1
  • 11
0

I have been looking everywhere for references on a feature like this, myself.

I don't have enough rep to comment, but Naveen's answer worked for me after I started going one line at a time with console.log("PASS");. If the function is never called on an event like keyup, then it likely means one of the variable names is wrong or there is bad syntax. The reason you could not get any calls to the javascript was because of a missing }); which is an ending statement for JQuery functions. The end of the code for the scripting part should appear like so:

           }
        }); //END $.ajax
      }
    }
});         //END keyup function
Nondeplume
  • 33
  • 5
0

Using Razor, with T4MVC at an MVC5 project, we'll implement jQuery Autocomplete.

You should have inside your solution, one or more projects, and inside your project, among many other usual MVC5 things, the folders Models, Views and Controllers. And inside of them...

NuGet

Get the dependencies in place (your should know how to get them using Visual Studio):

Then put them in the BundleConfig.cs files, at the App_Start folder:

using System.Web.Optimization;

namespace MyProject.Web
{
    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles
                .Add(new ScriptBundle("~/bundles/jquery")
                    .Include(
                        "~/Scripts/jquery-{version}.js",
                        "~/Scripts/jquery-ui.js",
                    ));

            bundles
                .Add(new StyleBundle("~/Content/css")
                    .Include(
                        "~/Content/jquery-ui.css"
                    ));
        }
    }
}

This will add the dependencies you´ll need to the view (see View section down below for more instructions).

Model

namespace MyProject.Web.Models.MyModelFolder
{
    public class MyModel
    {
        public string MyValue { get; set; }
        public string MyAnotherValue { get; set; }
        public string AndAnotherValue { get; set; }
    }
}

View

(Using Bootstrap)

@model MyProject.Web.Models.MyModelFolder.MyModel

<div class="ui-widget">
   @Html.LabelFor(model => model.MyValue)
   @Html.EditorFor(model => model.MyValue, new { htmlAttributes = new { @class = "form-control", id = "myTextbox" } })
   @Html.ValidationMessageFor(model => model.MyValue, "", new { @class = "text-danger" })
</div>

We'll be querying the MyValue field.

And add the dependencies from the BundleConfig.cs where you'll need them in your page:

<header>
    @Styles.Render("~/Content/css")
</header> 

<body>
   <p>Your Content</p>

   @Scripts.Render("~/bundles/jquery")
</body>

Adding the Autocomplete

There are two ways you can accomplish this, as:

  • Internal file to the page or,
  • as an external .js file.

NOTE: Autocomplete must be always below the required jQuery dependencies.

Internal file

In the .cshtml file. Inside your <body> tag, at the bottom of it:

<script>
   $("#myTextbox").autocomplete({
      source: '@Url.Action(MVC.MyController.MyMethod())'
   });
</script>

Or instead in the...(Choose one, not both!)

External file

In the Scripts folder. Remember to add this block at the bottom of your view to call the function from the outside.

@section Scripts {
    <script src="~/Scripts/autocomplete.js"></script>
}

And in the Scripts folder in a JS file add:

$(document).ready(function () {
    $("#myTextbox").autocomplete({
        source: '/MyController/MyMethod',
    });
})

You can see there the method you'll be calling from from the controller.

Controller

#region jQuery Method Calls

   using MyProject.Web.Models.MyModelFolder;

   public virtual JsonResult MyMethod(string term)
   {

      // _myViewModel is a partial model
      List<MyModel> MyAutocompleteList = new List<MyModel>();

      /* In this example I´m using AutoMapper, and getting back the List
      from the Database (layer, using Entity Framework), using Repository 
      Pattern (layer) and Unit of Work Pattern. */
      // But you can get the List however way you want.
      MyAutocompleteList = _theMapper.GetMyModelList(_operationsLayerService.GetMyModelList());
      
      // This LINQ query makes the magic happen
      var result = from U in MyAutocompleteList
                     where U.MyValue.Contains(term)
                     // It retrieves a composed string, not just a single value.
                     select  new { value = $"{U.MyValue} | {U.MyAnotherValue} {U.AndAnotherValue}" };

      // Security vulnerabilities? https://stackoverflow.com/a/21453075/7389293
      return Json(result, JsonRequestBehavior.AllowGet);
   }

#endregion

That's it.

carloswm85
  • 1,396
  • 13
  • 23