This project is read-only.

Server Side Support?

Aug 28, 2013 at 10:01 PM
Does this thing support server side sorting and paging? It does not appear so. It's pretty much useless if it doesnt. Programmers should strive for efficiency and returning the entire record-set is anything but efficient.
Aug 29, 2013 at 4:42 AM
Hi, yes the grid support server side paging and sorting, why you think so?
Feb 24, 2014 at 2:14 AM
Edited Feb 24, 2014 at 6:20 PM
I'm having an issue supporting Server Side code that I wrote.

I have a View that uses a View Model class I made. Then I have a method that converts the Entity Framework Schema Model into a IEnumerable property in View Model class. I have Grid.Mvc use that IEnumerable.

The problem is I need to have my method that converts my Schema Model to my View Model be the one that does OrderBy(x => x.Column).Skip(((qs.Page ?? 1) - 1) * pageSize).Take(pageSize). I need to do it before I assign the values to the View Model IEnumerable property. If I don't, all records get returned from that database.

The MVVM is very common and best practice. I don't see how this grid supports it. Is there any way to get it working in my scenario?
Feb 24, 2014 at 3:04 AM
You can use built-in grid paging and Grid.Mvc will create expressions like .Skip(N).Take(N) for you, when user navigates on grid pages.

All you need is pass IQueryable<TViewModel> to the view:
        public ActionResult Index()
        {
            return View(GetGridItems());
        }

private IQueryable<MyViewModel> GetGridItems()
{
       return _db.Models.Select(model => new MyViewModel { 
                // enumerate fields mapping
      });
}
Feb 24, 2014 at 4:52 AM
Bukharin wrote:
You can use built-in grid paging and Grid.Mvc will create expressions like .Skip(N).Take(N) for you, when user navigates on grid pages.

All you need is pass IQueryable<TViewModel> to the view:
        public ActionResult Index()
        {
            return View(GetGridItems());
        }

private IQueryable<MyViewModel> GetGridItems()
{
       return _db.Models.Select(model => new MyViewModel { 
                // enumerate fields mapping
      });
}
I see, that wont work in my current project I'm trying to implement Grid.Mvc. Reason is that I have to call .ToList() on my Entity Framework Query before the field mappings, because I have some code that doesn't translate into linq expressions. So I get an error when I try and execute my code without calling to ToList().

I tried calling @Html.Partial("_GridPager", Model.Pager, "Page") so I can have my repository method handle server side paging, but for some reason the partial page doesn't make the current page "active" (css class). Model.CurrentPage is always "1" . Other than that it seems to work. Not sure what i'm doing wrong
Feb 24, 2014 at 5:13 PM
ensure that you enable paging:
            grid.EnablePaging = true;
            grid.Pager.PageSize = 10;
Also ensure that you pass 'grid-page' query parameter with corrent number format. Code that determine current page:
string currentPageString = _context.Request.QueryString[ParameterName] ?? "1";
                if (!int.TryParse(currentPageString, out _currentPage))
                    _currentPage = 1;
                if (_currentPage > PageCount)
                    _currentPage = PageCount;
                return _currentPage;
Feb 24, 2014 at 5:55 PM
Edited Feb 24, 2014 at 6:34 PM
Bukharin wrote:
ensure that you enable paging:
            grid.EnablePaging = true;
            grid.Pager.PageSize = 10;
Do you know where abouts I apply this code? I'm not sure how to get a reference to the grid so I can set those properties.

I think this might be it, in my controller I have:
         vm.SearchGrid = new Grid<SearchRequestsListViewModel>(vm.SearchRequestsListViewModels)
         {
                EnablePaging = true,
                Pager = {PageSize = 10}
          };
          vm.SearchGrid.AutoGenerateColumns();
And in my view, I have:
          @Html.Partial("_Grid", Model.SearchGrid)
Feb 24, 2014 at 6:29 PM
Edited Feb 24, 2014 at 6:32 PM
Also ensure that you pass 'grid-page' query parameter with corrent number format. Code that determine current page:
string currentPageString = _context.Request.QueryString[ParameterName] ?? "1";
                if (!int.TryParse(currentPageString, out _currentPage))
                    _currentPage = 1;
                if (_currentPage > PageCount)
                    _currentPage = PageCount;
                return _currentPage;
I have modified my code to look like this in my repository, get ViewModel method:
         var count = requests.Count();
         var pager = new GridPager
                {
                    ItemsCount = count,
                    PageSize = 10,
                    MaxDisplayedPages = (int)Math.Ceiling((double)count / 10),
                    ParameterName = "CurrentPage"
                };
Then to test it, I opened my URL @ http://localhost/[myWebApp]/SearchRequests?System=AL&CurrentPage=2
           int currentPage;
           if (!int.TryParse(qs.CurrentPage, out currentPage))
                currentPage = 1;
           if (currentPage > pager.MaxDisplayedPages)
                currentPage = pager.MaxDisplayedPages;
CurrentPage, being 2, passes over both "IF.." statements, which seems correct. However when the page finishes loading, <li> <a class=active></li> is #1, and not #2 like it should be. Same with page 3 and 4, list item 1 remains "active"(css class).

Any ideas?
Feb 25, 2014 at 10:58 PM
Edited Feb 25, 2014 at 11:07 PM
I downloaded the source code and stepped through it. I think I found the issue:

My code used to read like
      var pager = new GridPager();
      pager.TemplateName = "_GridPager";
      pager.MaxDisplayedPages = (int)Math.Ceiling((double)count / pageSize);
      pager.PageSize = pageSize;
      pager.ItemsCount = count;
      pager.ParameterName = "CurrentPage";
I changed it to:
      var pager = new GridPager();
      pager.ParameterName = "CurrentPage";
      pager.TemplateName = "_GridPager";
      pager.MaxDisplayedPages = (int)Math.Ceiling((double)count / pageSize);
      pager.PageSize = pageSize;
      pager.ItemsCount = count;
Notice I set pager.ParameterName = "CurrentPage"; first, before setting the other properties.

The nearest I can figure is that, when you "set" "ItemsCount" OR "MaxDisplayedPages" property, the source code in "GridPager.cs" calls RecalculatePages();

Image

When "RecalculatePages()" gets called, it then calls "Get" on the "CurrentPage" property.

When "Get" is called on the "CurrentPage property", it processes the "Get" code:
public int CurrentPage
{
    get
    {
        if (_currentPage >= 0) return _currentPage;
        string currentPageString = _context.Request.QueryString[ParameterName] ?? "1";
        if (!int.TryParse(currentPageString, out _currentPage))
            _currentPage = 1;
        if (_currentPage > PageCount)
            _currentPage = PageCount;
        return _currentPage;
    }
    protected internal set
    {
        _currentPage = value;
        if (_currentPage > PageCount)
            _currentPage = PageCount;
        RecalculatePages();
    }
}
It's setting itself on the "Get" call. Because the first time it's called, it set's itself to 1, forever to be 1;

That would explain why
@Model.CurrentPage 
in the Partial View "_GridPager.cshtml" was always returning "1", which I was complaining about earlier in this thread.

*Note: I called my pager.ParameterName "CurrentPage". This is named the same as the CurrentPage Property in the source code just by coincidence. You could name your pager.ParameterName anything you want.
Feb 25, 2014 at 11:21 PM
Feb 26, 2014 at 2:34 AM
Another issue I found with a server side repository handling all the sorting and paging work.

internal class OrderByGridOrderer<T, TKey> : IColumnOrderer<T> in "OrderByGridOrderer.cs".

I had to comment out "ApplyOrder" method because it was causing my ordering to be very strange. Essentially there's no point in ordering a second time if I'm already ordering in my repository method.

I had to change the code to look like
public IQueryable<T> ApplyOrder(IQueryable<T> items, GridSortDirection direction)
{
    //switch (direction)
    //{
    //    case GridSortDirection.Ascending:
    //        return items.OrderBy(_expression);
    //    case GridSortDirection.Descending:
    //        return items.OrderByDescending(_expression);
    //    default:
    //        throw new ArgumentOutOfRangeException("direction");
    //}
    return items;
}
Course I was only able to do this because I'm referencing the source code instead of the library