当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - How to add progress indicator when searching on index view

问题描述:

I have a standard Index controller action that includes searching and sorting, here's the simplified controller action.

How do I add a progress indicator when the user types in a search term and the results take a while to get from the database? I'm confused as to whether I need to use Jquery or Microsoft ajax, etc.

I'm using MVC 5 with entity framework.

 public ActionResult Index(string sortOrder,

string currentFilter,

string searchString,

int? page)

{

if (Request.HttpMethod == "GET")

{

searchString = currentFilter;

}

else

{

page = 1;

}

ViewBag.CurrentFilter = searchString;

var invoices = from i in db.Invoices

select i;

invoices = invoices.OrderByDescending(s => s.InvoiceDate);

int pageSize = 20;

int pageNumber = (page ?? 1);

return View(invoices.ToPagedList(pageNumber, pageSize));

}

网友答案:

I would have an action that returns a PartialViewResult. Then, on your view, have a container (div or something) that contains the partial view. When you load index, the partial would be populated with the data in your viewmodel. Then, when the user searches, you make an ajax call (with jQuery or similar) to the action that returns the partial. The results of that action would then replace the contents of the container that contained your original results. Before that ajax call is made, you can use jQuery to show a progress indicator of your choice and upon completion/success, hide it again.

Let me know if you need full code examples.

-- Here is a basic example (not knowing anything else about your code/setup):

-- NOTE: this is just one of MANY ways you could do this :)

I hope this helps!

Create a class IndexViewModel that will be the model for your index view. The viewModel will contain everything you need for your index page - including a list of invoices

public class IndexViewModel
{
    // .. 
    public List<Invoice> Invoices { get; set; }
    // .. 
}

Create your index controller action that returns an IndexViewModel:

[HttpGet]
public ViewResult Index()
{
    var model = new IndexViewModel
    {
        // ..
        // call to private method SearchInvoices with default values
        Invoices = this.SearchInvoices("ASC", string.Empty, string.Empty, 0)
        //..
    };

    return this.View(model);
}

Create another controller action for searching that will return a partial view. (this will be called via jQuery/AJAX

public PartialViewResult Search(string sortOrder, string currentFilter, string searchString, int? page)
{
    var invoices = this.SearchInvoices(sortOrder, currentFilter, searchString, page);
    return this.PartialView("_SearchContent", invoices);
}

Here is the implementation of SearchInvoices

private List<Invoice> SearchInvoices(string sortOrder, string currentFilter, string searchString, int? page)
{
    // do your search work here (as you were in your original index action)
    // I would actually have this whole method implemented
    // in a separate service/business layer

    // ..
    var invoices = from i in db.Invoices select i;
    // ..

    return invoices.ToPagedList(pageNumber, pageSize);
} 

Then, your Index.cshtml view could look something like this:

@model IndexViewModel

<div class="row">
    <div id="searchFieldsRow" class="col-xs-12">
        <!-- code for all of your search fields or whatever -->
    </div>
</div>

<div class="row">
    <div id="myContent" class="col-xs-12">
        <!-- display your invoices here via Partial View -->
        @Html.Partial("_SearchContent", Model.Invoices)
    </div>
</div>

<div class="row">
    <div class="col-xs-12">
        <button type="button" id="searchButton">Search</button>
    </div>
</div>

<div id="loadingProgressOverlay" class="hidden">
    Loading...
</div>

<script type="text/javascript">
    (function ($) {
        $(document).ready(function () {

            // handle the click event of your search button
            $('#searchButton').click(function () {

                // show your progress indicator
                $('#loadingProgressOverlay').show();

                // assuming you have fields for these values
                var sortOrder = $('#sortOrder').val(),
                    currentFilter = $('#currentFilter').val(),
                    searchString = $('#searchString').val(),
                    page = $('#page').val();

                // make the ajax call to your Search action on your controller
                $.ajax({
                    url: 'ControllerName/Search',
                    data: {
                        sortOrder: sortOrder,
                        currentFilter: currentFilter,
                        searchString: searchString,
                        page: page
                    },
                    type: 'POST', // OR GET, whatever you want here
                    success: function (results) {
                        // upon success:
                        // - set the html of the myContent div to the PartialViewResult output
                        // - hide your progress indicator
                        $('#myContent').html(results);
                        $('#loadingProgressOverlay').hide();
                    },
                    error: function () {
                        // handle errors properly
                    }
                });
            });
        });
    })(jQuery);
</script>

The _SearchContent partial view:

@model List<Invoice>
<table class="table">
    <thead>
        <tr>
            <!-- stuff here -->
        </tr>
    </thead>
    <tbody>
        <!-- display the list of invoices however you like -->
        @Html.DisplayForModel()
    </tbody>
</table>
分享给朋友:
您可能感兴趣的文章:
随机阅读: