Search code examples
jqueryasp.net-mvcasp.net-corerazorvisual-studio-2022

How to update a table and refresh the partial view


I am using ASP.NET MVC and have a HomeController, model, and view. I am trying to create a search filter, where the user can type in some characters, click submit, and filter a table (in a partial view). The data is grabbed from a server, which I believe is fine. My problem is I can't seem to get the partial view to "refresh" correctly.

My HomeController:

public HomeController() 
{
    Debug.WriteLine("HomeController - HomeController()");
    listHomeData = new List<HomeTableData>();
}

public IActionResult Index()
{
    Debug.WriteLine("HomeController - IActionResult Index()");
    return View("Home", listHomeData);
}

public PartialViewResult OnGetMyPartial()
{
    Debug.WriteLine("HomeController - PartialViewResult OnGetMyPartial()");
    // ...Grabs data from server and puts into "listHomeData"...
    return PartialView("_HomeTablePartial", listHomeData);
}

My home view:

@using DCTS.Models
@model List<HomeTableData>
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Welcome Home</h2>
<p>The current time is: @DateTime.Now</p>
<form>
    <input type="text" id="searchText" name="searchText">
    <input type="submit" id="btnSubmit" value="Search">
</form>
<div id="divHomeTable">
    <partial name="~/Views/Shared/_HomeTablePartial.cshtml" model="@Model" />
</div>

I believe my problem (one of many I'm sure) is not understanding how to write the script part below. I've looked and searched for various tutorials, but everyone seems to do it slightly different from another. Some tutorials are also years old, so I don't know if their method is outdated or not. People also seem to be using older version of Visual Studio (I'm using 2022), so I don't know if that changes things or not. And I think I'm just getting confused and mixing these examples together, not knowing what is the correct method. Below is what I've tried and the results I got:

The script in my home view:

Attempt 1: (I haven't attempted to pass the search text... I'm just trying to get it to load for now...)

@section Scripts {
<script>
    $(document).ready(function () {
        var url = '@Url.Action("OnGetMyPartial", "Home")';
        $(function () {
            $('#btnSubmit').on('click', function () {
                $('#divHomeTable').load("/Home/OnGetMyPartial");
            });                
        });
    });
</script>

The above script seems to call my function in the HomeController, but it also seems to reload the entire page. When I click the button, the messages I get on my debugger shows that it calls my HomeController() then OnGetMyPartial(), and then it calls HomeController() again and then Index(). So, it's like it works, but then refreshes the page so it starts over at the beginning, showing nothing.

Attempt 2:

@section Scripts {
<script>
    $(document).ready(function () {
        $.ajax({
            type: "POST",
            url: '@Url.Action("Home", "OnGetMyPartial")',
            contentType: "application/x-www-form-urlencoded; charset=UTF-8",
            dataType: "html",
            success: function () {
                alert('success')
            },
            error: function () {
                alert('error')
            }
        });
    });
</script>

I saw this type of scripting and thought I give this a shot, but I only end up in the error side. I'm not sure how to figure out what the error is.

Attempt 3: Lastly, there was one tutorial i really liked (about 5 years old) but got stuck when he got into the partial view refresh part. He started typing in the following in the Home View:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    AjaxOptions ajaxOptions = new AjaxOptions
    {
        HttpMethod = "POST",
        InsertionMode = InsertionMode.Replace,
        UpdateTargetId = "divhomeTable"
    };
}

Do I need Microsoft.jQuery.Unobtrusive.Ajax nuget installed? I installed it but couldn't get my visual studio to recognize "AjaxOptions". Below is what I have referenced in my _Layout view:

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)

I also saw some other javascripting examples, but again I think I'm just confusing all of these different examples and don't have a clear line to go with.

Any direction or guidance or full tutorial link is really appreciated. If I can clear up any information, please ask. Thank you


Solution

  • According to your description, I think using the ajax to partial update the table partial view is the right solution.

    The ajax's error is if the server side return the error like 404 ,400 or else, it will trigger the error delegate function.

    More details about how to use it, you could refer to below example .

    HomeController:

        public IActionResult Index()
        {
            List<string> listHomeData = new List<string> { "test", "test1", "test2" };
            return View(listHomeData);
        }
    
        [HttpGet]
        public PartialViewResult OnGetMyPartial(string searchText)
        {
    
            // you could define the listhomedata by yourself.
           List<string> listHomeData = new List<string> { "update" , "update1", "update2" };
            return PartialView("_HomeTablePartial", listHomeData);
        }
    

    View:

    @{
        ViewData["Title"] = "Home Page";
    }
    @model List<string>
    
    
    <h2>Welcome Home</h2>
    <p>The current time is: @DateTime.Now</p>
    <form id="searchForm">
        <input type="text" id="searchText" name="searchText">
        <input type="submit" id="btnSubmit" value="Search">
    </form>
    <div id="divHomeTable">
        <partial name="~/Views/Shared/_HomeTablePartial.cshtml" model="@Model" />
    </div>
    
    @section Scripts {
        <script>
            $(document).ready(function () {
                $('#searchForm').on('submit', function (event) {
                    event.preventDefault(); // Prevent the form from submitting the traditional way
                    var searchText = $('#searchText').val();
                    $.ajax({
                        url: '@Url.Action("OnGetMyPartial", "Home")',
                        type: 'GET',
                        data: { searchText: searchText },
                        success: function (result) {
                            $('#divHomeTable').html(result); // Replace the content of divHomeTable with the result
                        },
                        error: function () {
                            alert('Error loading data');
                        }
                    });
                });
            });
        </script>
    }
    

    Hometable partial view:

    @model List<string>
    
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Value</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>@item</td>
                    <td>@item</td>
                </tr>
            }
        </tbody>
    </table>
    

    Value passed to the backend method by using ajax:

    enter image description here

    Test result:

    enter image description here