1

I have a form which on button click will return a view of search results based on the given searchString.

@using (Html.BeginForm("Index", "Search"))
{
    <div id="search" class="input-group">
        @Html.TextBox("searchString", null, new { @id = "searchBox", @class = "form-control", @placeholder = "Search" })
        <div class="input-group-btn">
            <button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
        </div>
    </div>
}

This calls the Index action on the Search controller which gets results based on the searchString and populates a list of strongly typed model "SearchView"

public ViewResult Index(string searchString = "", int startIndex = 0, int pageSize = 5)
{
    List<SearchView> searchResults = 
        (from p in db.Products
         where p.code.Contains(searchString)
         select new { ID = p.ID, Table = "Product", Name = p.code, Controller = "Product" })
             .ToList()
             .Select(x => new SearchView { ID = x.ID, Table = x.Table, Name = x.Name, Controller = x.Controller }).ToList();

    searchResults.AddRange(
        (from p in db.Multimedias
         where p.name.Contains(searchString)
         where p.isActive == true
         select new { ID = p.ID, Table = "Image", Name = p.name, Controller = "Multimedia" })
             .ToList()
             .Select(x => new SearchView { ID = x.ID, Table = x.Table, Name = x.Name, Controller = x.Controller }).ToList()); 

    ViewBag.startIndex = startIndex;
    ViewBag.pageSize = pageSize;
    ViewBag.loadMore = searchResults.Count > startIndex + pageSize;

    return View(searchResults.Skip(startIndex).Take(pageSize));
}

The view then gets called which is simply a table list of results

<table class="table">
@foreach (var item in Model) 
{
    <tr>
        <td>
            <b>@Html.DisplayFor(modelItem => item.Table)</b><br />
            @Html.ActionLink(item.Name, "Details", item.Controller, new { @ID = item.ID }, null)
        </td>
    </tr>
}
@if (ViewBag.LoadMore)
{ 
    <tr>
        <td>
            <b> @Html.ActionLink("See more results...", "Index", "Search", new { @startIndex = ViewBag.startIndex + ViewBag.pageSize }, null)</b>
        </td>
    </tr>
}
</table>

My question is given this, how would I convert the view into a partial view and change the form so that it shows the partial view on each key press in the textbox?

EDIT: The accepted answer can work but required me to return a partial view and on the javascript use keyup rather than keypress along with removing whitespace to create a valid URL.

return PartialView("_Search", searchResults.Skip(startIndex).Take(pageSize));

$("#searchBox").keyup(function () {      
    $("#myPartialViewContainer").load('@Url.Action("IndexLive","Search")' + '?searchString=' + $('#searchBox').val() + '&startIndex=0' + '&pageSize=5');
});
Nick Spicer
  • 2,279
  • 3
  • 21
  • 26
  • 1
    You will need javascript/jquery and ajax. [This question.answer](http://stackoverflow.com/questions/29142422/rendering-partial-view-on-button-click-in-asp-net-mvc/29142790#29142790) should help you get started. Its does the 'search' on a button click but you could just as easily handle textbox `.keyup()` event (but I think once your try it you will probably stick with a button) –  Oct 12 '15 at 11:32

1 Answers1

1

Use ajax load instead of form submit to load your partial view.

View

  1. Create partial view container to hold the partial view result.

  2. In jquery textbox key press event, just call the partial view and loads in partial view container .

    @using (Html.BeginForm("Index", "Search"))
    {
         <div id="search" class="input-group">
           @Html.TextBox("searchString", null, new { @id = "searchBox", @class = "form-control", @placeholder = "Search" })
           <div class="input-group-btn">
            <button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
          </div>
          </div>
    
        <!--Hold partial view content-->
            <div id="myPartialViewContainer">        
            </div>
    
        <!--Include jquery-->
        <!--Scripts to help load partial view content in partial view container-->
            @section Scripts
             {
             $( document ).ready(function() {
                // On each key press this will execute
                $('#searchBox').keyup(function(e) { 
                // Following will load partial view in partial view container
                $("#myPartialViewContainer").load('@Url.Action("Search","Index")' + '?searchString =' + $('#searchBox').val()+ '&startIndex =0' + '&pageSize =5');
    
             });
             });
             }
     }
    
Andi AR
  • 2,678
  • 2
  • 23
  • 28
  • 1
    `.live()`??? It was depreciated in v1.7 and removed in v1.9. - it just needs to be `$('#searchBox').keyup(function() {` –  Oct 12 '15 at 11:39
  • Thanks with some little tweaks I got this answer to work, the search controller also needs to return a PartialView rather than a View, and keyup rather than keypress needs to be used as it doesn't register the latest character otherwise. – Nick Spicer Oct 12 '15 at 13:25