So i am trying to achieve the best (most user friendly and performant) way of having a html table updated with data that is queried for in a searchbox.
The user can search for something by typing in a searchbox, i want to reload that html table with no (visible) postbacks/reloads (if possible) and have it behave like it is dynamically refreshing the data.
What i have and what i am currently doing is the following: A Razor Html.TextBox(...) and a Javascript function that looks like this:
$(function () {
$('#txtSearchString').keyup(function () {
//Content to send
var searchvalue = $(this).val();
$.get('@Url.Action("Customers", "Home")', { "SearchValue": searchvalue });
});
});
Where 'txtSearchString' is the name/id of the Html.TextBox. When i type something in this txtbox, it goes to a HttpGet Action where i receive the 'searchvalue' and i query my database and return results matching my requirements. NOTE that this Action is the same action as the initial one that is loaded.
I than return my model (where this updated data resides), i can also clearly see when debugging that i have update results in my controller as well in my view when iterating over the list of results (ex, initial list contains 100 items, updated list contains 20) but still when the view is loaded, i am seeing the same results as initially loaded, it doesn't seem to upload the view in the browser.
I have no idea why this is so. I don't know if this is the best way of doing what i want to, i have no experience in Partial views and don't know if i better use that instead, but still whatever i end up using, i want to understand whats happening behind and resulting in this behavior.
If you have any question, need more clarification on anything, please ask me. Kind regards!
UPDATE:
This is how i populate/update my html table with the values from my model:
<table class="table table-hover trCursor">
<thead>
<tr>
<th scope="col">
@Html.ActionLink("Id", "Customers", new { sortOrder = ViewBag.DateSortParm })
</th>
<th scope="col">
@Html.ActionLink("Name", "Customers", new { sortOrder = ViewBag.NameSortParm })
</th>
<th>...</th>
</tr>
</thead>
@foreach (var customer in Model.Customers)
{
<tr onclick="location.href='@(Url.Action("CustomerDetail", "Customer", new { Id = customer.ID }))'">
@Html.HiddenFor(c => customer.ID)
<td scope="row">@customer.ID</td>
<td>@customer.CustomerName</td>
<td>...</td>
</tr>
}
Where i can see that "Model.Customers" has the updated values when iterating over it.
When you use ajax (your
$.get()
function, you are making a call to a server method which in you case returns html, but you then need to do something with it - in your case, add it to the DOM in the `success callback.Because you are only interested in updating the
<tbody>
in your view to display the filtered rows, your method should return a partial view of only that, so start by creating a partial, say_Customers.cshtl
and delete the
@foreach (var customer in Model.Customers){ ... }
code in the main view and replace withNow create a separate controller method, say
and modify the ajax call to update the table body in the
success
callbackHowever, since you are initially displaying all Customers in the view, there is no need to make an ajax call in this case (and doing on each
.keyup
event will affect performance), since the data is already in the DOM. Instead you can just use javaScript to loop each row in the table body, and show or hide roes based on the search string. For a simple example, refer Filter table rows based on select value.