skip to Main Content

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

2

Answers


  1. 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

    Login or Signup to reply.
  2. The three samples you showed all send network requests, hoping that the server will do a filter query and then give you the data. But from your previous description, the server is not under your control, so the filtering function can only be implemented locally.

    You can use Linq to filter the obtained data and then pass it to the distributed view

    You can refer to the following code. Use Linq query to filter the data in Index

    Controllers

    public class MyHomeController : Controller
    {
        public List<HomeTableData> listHomeData { get; set; }
        public MyHomeController()
        {
            Debug.WriteLine("HomeController - HomeController()");
            listHomeData = new List<HomeTableData>() { 
                new HomeTableData() { Id = 1, Name = "HAA" },
                new HomeTableData() { Id = 2, Name = "QQQ" },
                new HomeTableData() { Id = 3, Name = "AAA" },
                new HomeTableData() { Id = 4, Name = "BBB" },
            };
        }
    
    
        public IActionResult Index(Query query)
        {
            Debug.WriteLine("HomeController - IActionResult Index()");
            if(!string.IsNullOrEmpty(query.searchText))
            {
                return View("Index", listHomeData.Where(p => p.Name.Equals(query.searchText)).ToList()); 
            }
    
            return View("Index", listHomeData);
        }
    
        public PartialViewResult OnGetMyPartial()
        {
            Debug.WriteLine("HomeController - PartialViewResult OnGetMyPartial()");
    
            return PartialView("_HomeTablePartial", listHomeData);
        }
    }
    

    Models

        public class Query
        {
            public string searchText { get; set; }
        }
    
        public class HomeTableData
        {
            public int Id { get; set; }
    
            public string Name { get; set; }
        }
    

    Views

    @model List<HomeTableData>
    @{
        Layout = null;
    }
    <html>
    <head>
        <title>MyHome</title>
    </head>
    <body>
        <h2>Welcome Home</h2>
        <p>The current time is: @DateTime.Now</p>
        <form asp-controller="MyHome" asp-action="Index" method="post">
            <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>
    </body>
    </html>
    
    @model List<HomeTableData>
    @{
        Layout = null;
    }
    <html>
    <head>
        <title>MyHome</title>
    </head>
    <body>
        <table>
            <tr>
                <td>Id</td>
                <td>Name</td>
            </tr>
            @foreach(var item in Model)
            {
                <tr>
                    <td>@item.Id</td>
                    <td>@item.Name</td>
                </tr>
            }
        </table>
    </body>
    </html>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search