This post provides a solution to a common scenario that is required in an application to search a data model against a certain search value.
Introduction
A common scenario that is required in an application is to search a data model against a certain search value. Due to the nature of the http protocol (being stateless):
- The submit of the search result will render the page again.
- The search expression entered will be lost.
One common solution to this problem is to create an asynchronous http request using jquery to just redraw the part which will hold the search result.
Example
1. Create a new ASP.NET MVC Core application in Visual Studio 2019 as follows:
2. Add a model under the models folder with name ShopInfoModel
, place the following code in the model
public class ShopInfoModel
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Pincode { get; set; }
}
3. In the controllers folder replace code of home controller with code below
public class HomeController : Controller
{
public HomeController()
{
}
public IActionResult IndexDisplaySearchWithAjaxRequest()
{
return View();
}
public IActionResult Index()
{
return View(new ShopInfoSearchModel { shops = new List<ShopInfoModel>() });
}
[HttpGet]
public IActionResult Search(string name)
{
List<ShopInfoModel> shops = new List<ShopInfoModel>
{
new ShopInfoModel{Name="Model1",Pincode=1},
new ShopInfoModel{Name="Model2",Pincode=2},
};
shops = shops.Where(w => w.Name.Contains(name)).ToList();
return Json(shops);
}
[HttpPost]
public IActionResult Search(ShopInfoSearchModel searchModel)
{
List<ShopInfoModel> shops = new List<ShopInfoModel>
{
new ShopInfoModel{Name="Model1",Pincode=1},
new ShopInfoModel{Name="Model2",Pincode=2},
};
searchModel.shops = shops.Where(w => w.Name.Contains(searchModel.SearchText)).ToList();
return View("Index", searchModel);
}
}
...
4. Under views\home folder add a view named IndexDisplaySearchWithAjaxRequest
. Place the following code in the view as follows
@{
ViewData["Title"] = "Home Page";
}
<table>
<tr>
<td><input type="text" id="txtsearch" /></td>
<td><button type="button" id="btnsearch">Search</button></td>
</tr>
</table>
@section Scripts
{
<script>
$(document).ready(function () {
$("#btnsearch").click(function()
{
$.ajax({
url: '@Url.Action("Search", "Home")',
data: { "name": $("#txtsearch").val()},
success: function (data)
{
var table = $("<table />");
for (var i = 0; i < data.length; i++) {
var row = $('<tr><td>' + data[i].name
+ '</td><td>' + data[i].address + '</td><td>' + data[i].pincode + '</td></tr>');
$('table').append(row);
}
}
});
}
)
})
</script>
}
...
5. Run the application, add Home/IndexDisplaySearchWithAjaxRequest to the URL in the address and press enter
Now we come to the heart of the article. The solution in this article presents a server side approach (i.e., returning the result absolutely from the controller to the view). This will reduce the amount of time needed to:
- create table rows by creating a
string
in jquery, which hold the table row and the row cells - repeat a
concat
operation for every table cell
As appear in step 4 above
Adding the Search Model
- Add a new model under models folder. Name it ShopInfoSearchModel.cs
- Add the following code in the class
public class ShopInfoSearchModel
{
public List<ShopInfoModel> shops { get; set; }
public string SearchText { get; set; }
}
}
...
Modifying Home Controller
- Add a new model under models folder. Name it ShopInfoSearchModel.cs
Replace code of index method in the home controller with the following code
public IActionResult Index()
{
return View(new ShopInfoSearchModel { shops = new List<ShopInfoModel>() });
}
...
- Add the following method in the home controller
[HttpPost]
public IActionResult Search(ShopInfoSearchModel searchModel)
{
List<ShopInfoModel> shops = new List<ShopInfoModel>
{
new ShopInfoModel{Name="Model1",Pincode=1},
new ShopInfoModel{Name="Model2",Pincode=2},
};
searchModel.shops = shops.Where(w => w.Name.Contains(searchModel.SearchText)).ToList();
return View("Index", searchModel);
}
}
...
Modify Home View
Replace code in the home/index.cshtm with the following
@{
ViewData["Title"] = "Home Page";
}
@using (Html.BeginForm("Search", "Home", FormMethod.Post))
{
<table>
<tr>
<td>@Html.TextBoxFor(f => f.SearchText)</td>
<td><button type="submit">Search</button></td>
</tr>
@foreach (var item in Model.shops)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
<td>
@Html.DisplayFor(modelItem => item.Pincode)
</td>
</tr>
}
</table>
}
...
When running the application, search against the model will be executed by clicking the search button and will give the same result as the ajax request approach
History
- 27th May, 2021: Initial version