Autocomplete with MVC 4 / Razor

2019-03-12 16:11发布

I think I am missing something obvious while attempting to add autocomplete functionality in MVC 4. From what I have found in other posts I have been able to put together an example however the method in my controller is not being called.

What I have tried so far...

_Layout

@Styles.Render("~/Content/themes/base/css")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryui")
@Scripts.Render("~/bundles/jqueryval")

Controller

Public Function Numbers(term As String) As ActionResult
    Return Json(New String() {"one", "two", "three", "four", "five", "six"}, JsonRequestBehavior.AllowGet)
End Function

View (I have hard coded the Home/Numbers for now)

<div class="editor-label">
    @Html.LabelFor(Function(model) model.Number)
</div>
<div class="editor-field">
    @Html.EditorFor(Function(model) model.Number)
    @Html.ValidationMessageFor(Function(model) model.Number)
</div>

<script type="text/javascript">
    $(function () {
        $("#Number").autocomplete({
            source: 'Home/Numbers',
            minLength: 1
        });
    });
</script>

When I run my app and type in the textbox nothing happens. I have put a breakpoint in the "Numbers" function and it seems that it is never called.

My project can be found here http://www.filedropper.com/testapp

4条回答
劫难
2楼-- · 2019-03-12 16:38

If you have the @Scripts.Render lines at the bottom of the body element in the layout and after the @RenderBody() you need to put your script in the scripts section:

@section scripts
<script type="text/javascript">
    $(function () {
        $("#Number").autocomplete({
            source: '@Url.Action("Numbers","Home")',
            minLength: 1
        });
    });
</script>
End Section

Because your script depends on jQuery so jQuery should be loaded first.

Or just move your @Scripts.Render declaration into the head in the layout then you don't need to put your code into the scripts section (but you are better off with using the section)

查看更多
萌系小妹纸
3楼-- · 2019-03-12 16:38

For Viewpage

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>

<input type="text" id="txtmasterserach" name="txtmasterserach" placeholder="City, region, district or specific hotel"  autocomplete="off"/> 
 <input type="hidden" name="hidenkeyvalues" id="MovieID" /> 

<script type="text/javascript">
    $(document).ready(function () {
        $("#txtmasterserach").autocomplete({
            source: function (request, response) {
                $.ajax({
                    url: "/Company/getautobox",
                    type: "POST",
                    dataType: "json",
                    data: { Prefix: request.term },
                    success: function (data) {
                        response($.map(data, function (item) {
                            return { value: item.Id, label: item.name };
                        }))
                    }
                })
            },
            select: function (event, ui) {
                $("#MovieID").val(ui.item.value);
                $("#txtmasterserach").val(ui.item.label);
                event.preventDefault();
                return false;
            },
            focus: function (event, ui) {
                $("#MovieID").val(ui.item.value);
               // $("#txtmasterserach").val(ui.item.label);
                event.preventDefault();
                return false;
            },
            messages: {
                noResults: "", results: ""
            }
        });
    });
    </script>

For Controller :

public class companyController : Controller
{
public JsonResult getautobox(String Prefix)
    {
        SqlConnection con = new SqlConnection();
        con.ConnectionString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
        SqlCommand cmd = new SqlCommand("procedurename", con);
        cmd.Parameters.AddWithValue("@prefix", Prefix);
        cmd.CommandType = CommandType.StoredProcedure;
        DataSet ds = new DataSet();
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(ds);
        List<autosearchdatalist> auto = new List<autosearchdatalist>();
        if (ds.Tables[0].Rows.Count > 0)
        {
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                auto.Add(new autosearchdatalist
                {
                    Id = ds.Tables[0].Rows[i]["Id"].ToString(),
                    name = ds.Tables[0].Rows[i]["hotelname"].ToString()
                });
            }
        }
        if (ds.Tables[1].Rows.Count > 0)
        {
            for (int i = 0; i < ds.Tables[1].Rows.Count; i++)
            {
                auto.Add(new autosearchdatalist { 
                    Id = ds.Tables[1].Rows[i]["Id"].ToString(),
                    name = ds.Tables[1].Rows[i]["hotelname"].ToString() 
                });
            }
        }
        if (ds.Tables[2].Rows.Count > 0)
        {
            for (int i = 0; i < ds.Tables[2].Rows.Count; i++)
            {
                auto.Add(new autosearchdatalist
                {
                    Id = ds.Tables[2].Rows[i]["Id"].ToString(),
                    name = ds.Tables[2].Rows[i]["hotelname"].ToString()
                });
            }
        }
        String msg = "";
        return Json(auto);
    }
}

Keep router setting default otherwise action will not call

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "company", action = "Index", id = UrlParameter.Optional }
        );
    }
}
查看更多
男人必须洒脱
4楼-- · 2019-03-12 16:59

I suggest you to control errors in Chrome to ensure that jQuery libraries working properly. if there is no problem, Try this script :

$(document).ready(function () { 
    $("#Number").each(function () {
        $(this).autocomplete({ source: $(this).attr("data-autocomplete") });
    });
});

Then in your Razor (C#):

<input type="text" id="Number" data-autocomplete="@Url.Action("Action","Controller")" autocomplete="on" />

If you want to use Razor Html Helpers instead of using 'input' tag, The id attribute is the same name of Model.Member. Notice that in Controller, you must input string with the 'term' name, as written in your code. For security reasons, you must avoid using parameters in js file that shows the site technology. The method declared above never uses js file to get address of resource.

查看更多
登录 后发表回答