This is a migrated thread and some comments may be shown as answers.

[Solved] Loosing sort value when Grouping Grid

12 Answers 214 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Oliver
Top achievements
Rank 1
Oliver asked on 23 Feb 2012, 04:34 PM
Hi,

I have a Grid ajax-bounded and if add a grouping value i lost the current sorting for my model.
my controller-method watch like:
[GridAction]
public ActionResult _ShowSupplierNewGTINs(string articleID, string supplierID)
 {
    List<DtoSupplierGtin> gtin = new List<DtoSupplierGtin>();
    var action = Request.QueryString["action"];
    if(action == "showAll")
       gtin = _service.GetArticleGTINs(ArticleID, suppID, userSession).ToList();
    else
        gtin = _service.GetArticleGTINs(ArticleID, suppID, userSession).Where(l => !string.IsNullOrEmpty(l.EAN) && l.HauptGTIN == 1).ToList();
 
   return PartialView(new GridModel<DtoSupplierGtin>
   {
         Data = gtin.OrderBy(e => e.LogID).ToList()
   });
}
and my Grid definition is like:
@(Html.Telerik().Grid<JanusCore.DTO.DtoSupplierGtin>()
    .Name("GtinGrid-" + ViewData["SupplierID"].ToString())
    .Columns(columns =>
    {
        columns.Bound(o => o.EAN)
            .HtmlAttributes(new { style = "text-align:right;" })
            .ClientTemplate("<#=EAN != '' && IsMainGTIN == 1 ? '*' + EAN : EAN #>")
            .Title("GTIN")
            .Width(25);
        columns.Bound(o => o.InhaltText)
            .HtmlAttributes(new { style = "white-space:nowrap;" })
            .Title("Inhalt")
            .Width(60);
     })
     .Groupable(grouping => grouping.Groups(groups =>
    {
        groups.AddDescending(c => c.InhaltText);
    }).Visible(false))
    .DataBinding(dataBinding => dataBinding.Ajax().Select("_ShowSupplierNewGTINs", "Show", new { articleID = ViewData["ArticleID"].ToString(), supplierID = ViewData["SupplierID"].ToString() }))
    .Pageable(pager => pager.PageSize(Int32.MaxValue))
 )
i tried to sort the model from the Repository too, but still no changes visible. is this a bug of Telerik MVC Grid? is there a workaround for this issue? Thx. Oliver

12 Answers, 1 is accepted

Sort by
0
Dadv
Top achievements
Rank 1
answered on 24 Feb 2012, 11:32 AM
Hi,

have you try to add  : .Sortable(sorting => sorting.SortMode(GridSortMode.MultipleColumn)) like in http://demos.telerik.com/aspnet-mvc/grid/sorting ?


0
Oliver
Top achievements
Rank 1
answered on 24 Feb 2012, 11:58 AM
Hi,
I don´t want to allow user sorting (.sortable() or .Sortable(sorting => sorting.SortMode(GridSortMode.MultipleColumn))), i just want to sort the Grid by LogID and then do grouping by "InhaltText".
0
Dadv
Top achievements
Rank 1
answered on 24 Feb 2012, 04:34 PM
hmm...

do you try : .Sortable(s => s.SortMode(GridSortMode.MultipleColumn).Enabled(false))  ?


0
Petur Subev
Telerik team
answered on 24 Feb 2012, 04:55 PM
Hello Oliver,

Basically to apply sorting on initial load you can use the Sorting configuration method when declaring your Grid.
e.g.
.Sortable(config=>config.OrderBy(c=>c.Add("UnitsOnOrder").Descending()))
.Groupable(settings => settings.Groups(groups => groups.(o => o.UnitsInStock)).Visible(true)
//...
If you want to change the direction order of the groups you can use the the AddDescending method
e.g.
... groups.AddDescending(o => o.UnitsInStock))



All the best,
Petur Subev
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
Oliver
Top achievements
Rank 1
answered on 27 Feb 2012, 08:52 AM
Hi Petur Subev,
Thanks for the Answer, but that dont´t change anything.
If i delete the Groupable(...) expression it work great and anything is sorted like i want, but when i add the Groupable expression to the grid, my viewmodel become disordered.

Oliver
0
Dadv
Top achievements
Rank 1
answered on 27 Feb 2012, 10:59 AM
Hi,

Can you explain the "disordered" with an example please?

if i understood what you are doing to do you should have 2 sort :

First by InhaltText (descending) , then by LogID (ascending)

If i'm true, grouping apply a sort "in first" by default, then your "order by" is apply after.

so if you want to by pass this in design sort, you probably need to use custom binding with custom grouping :


[GridAction]
public ActionResult _ShowSupplierNewGTINs(GridCommand command, string articleID, string supplierID)
 {
    List<DtoSupplierGtin> gtin = new List<DtoSupplierGtin>();
    var action = Request.QueryString["action"];
    if(action == "showAll")
       gtin = _service.GetArticleGTINs(ArticleID, suppID, userSession).ToList();
    else
        gtin = _service.GetArticleGTINs(ArticleID, suppID, userSession).Where(l => !string.IsNullOrEmpty(l.EAN) && l.HauptGTIN == 1).ToList();
  
var data = gtin.OrderBy(e => e.LogID).OrderByDescending(o=>o.InHaltText);
 

    var group  = data.GroupBy(g=>g.InHaltText).Select(s=>new AggregateFunctionsGroup{Key = s.Key, Items =s});
 
return PartialView(new GridModel
   {
         Data = group;
   });
}



@(Html.Telerik().Grid<JanusCore.DTO.DtoSupplierGtin>()
    .Name("GtinGrid-" + ViewData["SupplierID"].ToString())
    .Columns(columns =>
    {
        columns.Bound(o => o.EAN)
            .HtmlAttributes(new { style = "text-align:right;" })
            .ClientTemplate("<#=EAN != '' && IsMainGTIN == 1 ? '*' + EAN : EAN #>")
            .Title("GTIN")
            .Width(25);
        columns.Bound(o => o.InhaltText)
            .HtmlAttributes(new { style = "white-space:nowrap;" })
            .Title("Inhalt")
            .Width(60);
     })
     .Groupable(grouping => grouping.Enabled(true).Visible(false))
    .DataBinding(dataBinding => dataBinding.Ajax().Select("_ShowSupplierNewGTINs", "Show", new { articleID = ViewData["ArticleID"].ToString(), supplierID = ViewData["SupplierID"].ToString() }))
    .Pageable(pager => pager.PageSize(Int32.MaxValue))
.EnableCustomBinding(true)
 )



I did it directly in the post, test something like that and i think it will work.


Regards,

0
Oliver
Top achievements
Rank 1
answered on 27 Feb 2012, 02:32 PM
Hi Dadv,
I want first sort by LogID (ascending) and then group "InhaltText".
i tried your solution but i get a JavaScript error "Typ is not defined".

Thx.
Oliver
0
Dadv
Top achievements
Rank 1
answered on 27 Feb 2012, 02:43 PM
Like i wrote, i did not test it, just a idea for where to look (i don't have your model entities).

if you want to sort by LogID (ascending) and then group "InhaltText" you need to sort by "InhaltText"  before group.

so it's why i did this : gtin.OrderBy(e => e.LogID).OrderByDescending(o=>o.InHaltText); 

If you doesn't do that you probably have grouping problems.

in the second part, your javascript error is probably a conversion error in the grouping command.

Could you send a sample project with your model? then i could look for fix it.

Edit : a mistake in my code  : gtin.OrderBy(e => e.LogID).ThenByDescending(o=>o.InHaltText);  
0
Oliver
Top achievements
Rank 1
answered on 27 Feb 2012, 04:10 PM
Hi Dadv,
Thx for the quick reply.
here is a sample code that shows the problem .

oliver
0
Accepted
Dadv
Top achievements
Rank 1
answered on 28 Feb 2012, 09:14 AM
Hi,

here the change i made from your sample :

in the controller
[GridAction(EnableCustomBinding = true)]
        public ActionResult _ShowSupplierNewGTINs(GridCommand command, string articleID, string supplierID)
        {
            ViewData["SupplierID"] = "";
            ViewData["ArticleID"] = "";
            List<DtoSupplierGtin> gtin = new List<DtoSupplierGtin>();
            var action = Request.QueryString["action"];
            if (!string.IsNullOrEmpty(articleID) && !string.IsNullOrEmpty(supplierID))
            {
                Guid ArticleID = new Guid(articleID);
                Guid suppID = new Guid(supplierID);
                ViewData["SupplierID"] = supplierID;
                ViewData["ArticleID"] = ArticleID;
                if (action == "showAll")
                    gtin = GetArticleGTINs(ArticleID, suppID).ToList();
                else
                    gtin = GetArticleGTINs(ArticleID, suppID).Where(l => !string.IsNullOrEmpty(l.EAN) && l.HauptGTIN == 1).ToList();
 
                foreach (DtoSupplierGtin item in gtin)
                {
                    if (item != null)
                    {
                        item.IsMainGTIN = item.HauptGTIN == 1 ? true : false;
                        //item.BasismengeneinheitID = item.TempBasisMeID == null ? item.BasismengeneinheitID : item.TempBasisMeID;
                        item.Basismengeneinheit = string.IsNullOrEmpty(item.TempBasisMe) ? item.Basismengeneinheit : item.TempBasisMe;
                        item.InhaltText = "1 " + item.Bestellmengeneinheit + " enth. " + item.Inhalt + " " + item.Basismengeneinheit + (item.LogistischeEinheit > 0 ? " VE" + item.LogistischeEinheit : "");                      
                    }
                }
            }
 
            var data = gtin.OrderBy(e => e.TempInhalt).ThenByDescending(o => o.Inhalt).ToList();
                         
            var group = data.AsQueryable().ApplyGrouping(command.GroupDescriptors);
 
 
            return View(new GridModel
            {
                Data = group,
                Total = data.Count()
            });
        }

in the view
@(Html.Telerik().Grid<TestTelerikGrouping.Models.DtoSupplierGtin>()
      .Name("GtinGrid")
      .ToolBar(toolBar => toolBar.Template(
          @<text>
            <div style="width: 100%;">
            <button id='btnShowAll' class="t-button t-button-icontext" style="font-size: 12px;"><span class="t-icon t-refresh"></span>Alle GTINs anzeigen</button>
            <button id='btnShowMain' class="t-button t-button-icontext" style="font-size: 12px;"><span class="t-icon t-refresh"></span>Nur VE Haupt-GTINs anzeigen</button>
            </div>
          </text>))
    .Columns(columns =>
    {
        columns.Bound(o => o.EAN)
            .HtmlAttributes(new { style = "text-align:right;" })
            .ClientTemplate("<#=EAN != '' && IsMainGTIN == 1 ? '*' + EAN : EAN #>")
            .Title("GTIN").Width(25);
        columns.Bound(o => o.InhaltText)
            .HtmlAttributes(new { style = "white-space:nowrap;" })
            .Title("Inhalt")
            .Width(60);
        columns.Bound(o => o.TempInhalt)
           .Hidden();
        columns.Bound(o => o.InhaltText)
           .Hidden();
    })
    .Sortable(s=>s.Enabled(false))
    .Groupable(g=>g.Groups(gs=>gs.Add(a=>a.InhaltText)).Enabled(true).Visible(false))
    .DataBinding(dataBinding => dataBinding.Ajax().Select("_ShowSupplierNewGTINs", "Home", new { articleID = ViewData["ArticleID"].ToString(), supplierID = ViewData["SupplierID"].ToString() }))
    .Pageable()
    .EnableCustomBinding(true)
 )

the binding extension (extract and modify from the telerik custom ajax binding)
public static class CustomBindingExtensions
    {      
        public static IEnumerable ApplyGrouping(this IQueryable<DtoSupplierGtin> data, IList<GroupDescriptor>
            groupDescriptors)
        {
            Func<IEnumerable<DtoSupplierGtin>, IEnumerable<AggregateFunctionsGroup>> selector = null;
            foreach (var group in groupDescriptors.Reverse())
            {
                if (selector == null)
                {
                    if (group.Member == "InhaltText")
                    {
                        selector = orders => BuildInnerGroup(orders, o => o.InhaltText);
                    }
                }
                else
                {
                    if (group.Member == "InhaltText")
                    {
                        selector = BuildGroup(o => o.InhaltText, selector);
                    }
                }
            }
            return selector.Invoke(data).ToList();
        }
        private static Func<IEnumerable<DtoSupplierGtin>, IEnumerable<AggregateFunctionsGroup>>
            BuildGroup<T>(Func<DtoSupplierGtin, T> groupSelector, Func<IEnumerable<DtoSupplierGtin>,
            IEnumerable<AggregateFunctionsGroup>> selectorBuilder)
        {
            var tempSelector = selectorBuilder;
            return g => g.GroupBy(groupSelector)
                         .Select(c => new AggregateFunctionsGroup
                         {
                             Key = c.Key,
                             HasSubgroups = true,
                             Items = tempSelector.Invoke(c).ToList()
                         });
        }
        private static IEnumerable<AggregateFunctionsGroup> BuildInnerGroup<T>(IEnumerable<DtoSupplierGtin>
            group, Func<DtoSupplierGtin, T> groupSelector)
        {
            return group.GroupBy(groupSelector)
                    .Select(i => new AggregateFunctionsGroup
                    {
                        Key = i.Key,
                        Items = i.ToList()
                    });
        }
    }


it work fine for me, you just have to change this line : 
var data = gtin.OrderBy(e => e.TempInhalt).ThenByDescending(o => o.Inhalt).ToList(); 
by what you want to order (LogId?)

if you wish to change the grouping value (or add an other) simply add it in the binding extension :

if (selector == null)
                {
                    if (group.Member == "InhaltText")
                    {
                        selector = orders => BuildInnerGroup(orders, o => o.InhaltText);
                    }
                }
                else
                {
                    if (group.Member == "InhaltText")
                    {
                        selector = BuildGroup(o => o.InhaltText, selector);
                    }
                }

and in the view
.Groupable(g=>g.Groups(gs=>gs.Add(a=>a.InhaltText)).Enabled(true).Visible(false)) 


Don't forget to add the [GridAction(EnableCustomBinding = true)] attribute in the controller

That all,

Regards,

0
Oliver
Top achievements
Rank 1
answered on 28 Feb 2012, 10:53 AM
Hi Dadv,
It works like a charme ... many many Thx.
Great work.

Regards
Oliver
0
Dadv
Top achievements
Rank 1
answered on 28 Feb 2012, 11:44 AM
You'r welcome,
don't forget to mark as answer.
Tags
Grid
Asked by
Oliver
Top achievements
Rank 1
Answers by
Dadv
Top achievements
Rank 1
Oliver
Top achievements
Rank 1
Petur Subev
Telerik team
Share this question
or