MVC Paging and PageCount Partial Views

This entry is part 6 of 7 in the series Ultimate MVC Paging

Page Count Partial View

In order to keep the paging generic in MVC, I’ve set them up as two partial views. A MVC Paging and PageCount Partial Views. In the partial view, there is a parameter called refid that I didn’t use in the sample code, but it’s there to service a parent/child relationship. Let’s say you display a list of projects. The user clicks on a project and are displayed a list of tasks for that project. When the user clicks to go to the next page of the tasks, the query will need to pass through the ProjectID in order to “Filter” the values to still only be for the project that was selected. That’s where you’ll use the refid.

Also notice the use of the ISearchModel as the model. That’s because the view won’t allow a model defined generically.

// This won't work
@model SearchModel<TEntity>

By using the Interface, I can get around this restriction and the view will allow a SearchModel to be passed in with whichever collection is needed.

@using YTG.MVC.Lookups.Models

@model ISearchModel

<div>
    <center>
        Change Page Size:<br />
        <ul class="pagination justify-content-center">
            <li class="@(Model.PageSize == 25 ? "active strong" : "") page-item"><a class="page-link" href="#" onclick="GetPageSize(25)">25</a></li>
            <li class="@(Model.PageSize == 50 ? "active strong" : "") page-item"><a class="page-link" href="#" onclick="GetPageSize(50)">50</a></li>
            <li class="@(Model.PageSize == 100 ? "active strong" : "") page-item"><a class="page-link" href="#" onclick="GetPageSize(100)">100</a></li>
        </ul><br />
        Records on this Page: @Model.RecordCount<br />
        Total records found: @Model.TotalItems<br />
    </center>

</div>


<script type="text/javascript">

    function GetPageSize(PageSize) {

        var _url = "/@Model.controllerName/@Model.actionName";

        // Set the global values for sorting post back
        var searchModel = {};
        searchModel.SortColumn = '@Model.SortColumn';
        searchModel.PrevSortColumn = '' // Leave blank so sorting doesn't kick;
        searchModel.CurrentPage = @Model.CurrentPage;
        searchModel.PageSize = PageSize;
        searchModel.SearchTerm = '@Model.SearchTerm';
        searchModel.SearchFilter = '@Model.SearchFilter';
        searchModel.SortDescending = '@Model.SortDescending';
        searchModel.ActiveOnly = '@Model.ActiveOnly';
        searchModel.RefId = @Model.RefId;
        searchModel.RefUniqueId = '@Model.RefUniqueId';

        $.ajax({
            type: "POST",
            url: _url,
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(searchModel),
            dataType: "html",
            success: function (result, status, xhr) {
                $("#gridPartial").html(result)
            },
            error: function (xhr, status, error) {
                alert("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText)
            }
        });

    }

</script>

Paging Partial View

Just as above, this partial view is written to be generic, so it can be use all throughout your site without any special code for the particular page implementation.

@using YTG.MVC.Lookups.Models

@model ISearchModel
<!-- Pager -->
<nav>
    <ul class="pagination justify-content-center">
        @if (Model.CurrentPage > 1)
        {
            <li class="page-item"><a class="page-link" href="#" onclick="GetPaging(1)">First</a></li>
            <li class="page-item"><a class="page-link" href="#" onclick="GetPaging(@Model.CurrentPage - 1)">Previous</a></li>
        }

        @for (var displayPage = Model.StartPage; displayPage <= Model.EndPage; displayPage++)
        {
            <li class="@(displayPage == Model.CurrentPage ? "active" : "") page-item"><a class="page-link" href="#" onclick="GetPaging(@displayPage)">@displayPage</a></li>
        }

        @if (Model.CurrentPage < Model.TotalPages)
        {
            <li class="page-item"><a class="page-link" href="#" onclick="GetPaging(@Model.CurrentPage + 1)">Next</a></li>
            <li class="page-item"><a class="page-link" href="#" onclick="GetPaging(@Model.TotalPages)">Last</a></li>
        }
    </ul>
</nav>
<!-- /Pager -->

<script type="text/javascript">

    function GetPaging(ToPage) {

        var _url = "/@Model.controllerName/@Model.actionName";

        // Set the global values for sorting post back
        var searchModel = {};
        searchModel.SortColumn = '@Model.SortColumn';
        searchModel.PrevSortColumn = ''; // Leave blank so sorting doesn't kick;
        searchModel.CurrentPage = ToPage;
        searchModel.PageSize = @Model.PageSize;
        searchModel.SearchTerm = '@Model.SearchTerm';
        searchModel.SearchFilter = '@Model.SearchFilter';
        searchModel.SortDescending = '@Model.SortDescending';
        searchModel.ActiveOnly = '@Model.ActiveOnly';
        searchModel.RefId = @Model.RefId;
        searchModel.RefUniqueId = '@Model.RefUniqueId';

        $.ajax({
            type: "POST",
            url: _url,
            async: true,
            contentType: "application/json",
            data: JSON.stringify(searchModel),
            dataType: "html",
            success: function (result, status, xhr) {
                $("#gridPartial").html(result)
            },
            error: function (xhr, status, error) {
                alert("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText)
            }
        });

    }

</script>

I recommend that these are placed in your Shared folder under the Views folder.