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

Sorting and Filtering for Custom Object in Column doesn't work

3 Answers 1189 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Helga
Top achievements
Rank 1
Helga asked on 15 Oct 2013, 07:18 AM
Hello,
i'm new to KendoGrid and this is my first Project. I hope you can help me and forgive my bad english ;)

The Problem:
If I bind another Object to a Column which is included in the Object of the Row, sorting and filtering doesn't work anymore.
Each Row, I bind a "Adress" Object, include a "Country" Object. I use a ClientTemplate to show the "Description" Property (if not null).
I know that a ClientTemplate breaks the Sorting and Filtering, but i don't know how to solve this by the MVC Wrapper. I found no examples.

In Inline-Editormode I display for the Country-Object a Kendo-DropDownList for valid values. This works fine for CRUD.
For the Country Column in Read-Mode I've added a Custom Filter with a Kendo-DropdownList for the valid values, but there is a empty DropDownList for the Filter-Options (for ex. "ss equal to"...). So if i press "Filter" or sorting the Column, the Grid don't know how to sort/filter.

PS.: The Country is attached/connected by the EntityFramework(Designer) and the Models were created automatically.

The Question:
How can i solve my Problem? How can i implement with the MVC Wrapper a working sorting/filtering for an Object in a Column? And.... is there a better solution to bind a Object to a Column with a DropDownList?

Thank you for your help :)

Grid View
@{
    Layout = "~/Views/Shared/Layout.cshtml";
}
 
@model IEnumerable<LiCPSAdmin2.Models.Adressen>
 
@(Html.Kendo().Grid(Model)
    .Name("Adressen")
    .Columns(columns =>
    {
        columns.Command(command =>
        {
            command.Edit().Text(" ");
            command.Destroy().Text(" ");
        }).Width(90).HtmlAttributes(new { style = "background-color: rgb(238, 238, 238)" });
        columns.Bound(p => p.Eadr).Title("Adresse").Width(90).HtmlAttributes(new { style = "text-align:center;" });
        columns.Bound(p => p.Nama).Title("Name").Width(200);
        columns.Bound(p => p.Namb).Title("Name 2").Width(200);
        columns.Bound(p => p.Namc).Title("Strasse");
        columns.Bound(p => p.Namd).Title("Strasse 2");
        columns.Bound(p => p.Name).Title("Plz, Ort");
        columns.Bound(p => p.Namf).Title("Ort 2");
        columns.Bound(p => p.Pstc).Title("PLZ").Width(90).HtmlAttributes(new { style = "text-align:center;" });
        columns.Bound(p => p.Ccty).Title("Land").Width(90).HtmlAttributes(new { style = "text-align:center;" });
        columns.Bound(p => p.BaLand).Title("Bezeichnung").Width(200).ClientTemplate(" #= BaLand ? BaLand.Dsca : '' # ").Filterable(filter => filter.UI("BaLandFilter"));
    })
    .DataSource(dataSource => dataSource
        .Ajax()
        .PageSize(50)
        .Model(model =>
        {
            model.Id(p => p.Eadr);
            model.Field(p => p.Eadr).Editable(false);
        })
        .Events(events => events.Error("error_handler"))
        .Create(create => create.Action("Create", "Adressen"))
        .Read(read => read.Action("Read", "Adressen"))
        .Update(update => update.Action("Edit", "Adressen"))
        .Destroy(destroy => destroy.Action("Delete", "Adressen"))
    )
    .Events(events => events.Edit("edit_handler"))
    .ToolBar(toolbar => toolbar.Create())
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .Sortable(sortable => sortable.AllowUnsort(true).SortMode(GridSortMode.MultipleColumn))
    .Filterable(filter => filter.Extra(false))
    .ColumnResizeHandleWidth(5)
    .Scrollable(scrollable => scrollable.Virtual(true))
    .HtmlAttributes(new { style = "height:100%;" })
    .Navigatable(nav => nav.Enabled(true))
    .Resizable(resize => resize.Columns(true))
    .Reorderable(reordering => reordering.Columns(true))
    .Pageable()
)
 
<script type="text/javascript">
 
    function error_handler(e) {
        if (e.errors) {
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
            var grid = $("#Adressen").data("kendoGrid");
            grid.cancelChanges();
        }
    };
 
    function baland_change() {
        $("#Ccty").val(this.value()).css({ 'background-color': '#fff' }).trigger("change");
    }
 
    function edit_handler(e) {
        $(".k-grid-update").html("<span class=\"k-icon k-update\"></span>");
        $(".k-grid-cancel").html("<span class=\"k-icon k-cancel\"></span>");
 
        e.container.find("#Ccty").focusout(function () {
            e.container.find("#BaLand").data("kendoDropDownList").value($(this).val());
        });
    }
 
    function BaLandFilter(element) {
        element.kendoDropDownList({
            dataSource: {
                transport: {
                    read: "@Url.Action("FilterMenuCustomization_BaLand")"
                }
            },
            optionLabel: "Bitte wählen"
        });
    }
 
</script>
Editor Template for Countries (BaLand)
@(Html.Kendo().DropDownList()
    .Name("BaLand")
    .BindTo((System.Collections.IEnumerable)TempData["Land"])
    .DataTextField("Dsca")
    .DataValueField("Ccty")
    .OptionLabel("Bitte wählen")
    .Events(e => e
        .Change("baland_change")
    )
)

Adress Controller

public class AdressenController : Controller
    {
        private LiCPS_Develop_V20Entities db = new LiCPS_Develop_V20Entities();
 
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
 
        // Index
        public ActionResult Index()
        {
            TempData["Land"] = db.BaLand.ToList();
            var adressen = db.Adressen.Include(a => a.BaLand).Distinct();
            return View(adressen.ToList());
        }
 
        public ActionResult FilterMenuCustomization_BaLand()
        {
            return Json(db.BaLand.Select(e => e.Dsca).Distinct(), JsonRequestBehavior.AllowGet);
        }
 
        // Grid
        public ActionResult Read([DataSourceRequest] DataSourceRequest request)
        {
            return Json(((db.Adressen.Include(a => a.BaLand).Distinct()).ToList()).ToDataSourceResult(request));
        }
 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([DataSourceRequest] DataSourceRequest request, Adressen adressen)
        {
            if (adressen != null && ModelState.IsValid)
            {
                adressen.Eadr = Convert.ToInt32(HelperFunctions.getNextNumber(10, 2));
                db.Adressen.Add(adressen);
                db.Entry(adressen.BaLand).State = EntityState.Unchanged;
                
                try
                {
                    db.SaveChanges();
                }
                catch (InvalidOperationException ex)
                {
                    ModelState.AddModelError(string.Empty, "Es ist ein Fehler aufgetreten! Der Datensatz wurde nicht erstellt");
                }
                catch (DbEntityValidationException ex)
                {
                    ModelState.AddModelError(string.Empty, "Es ist ein Fehler aufgetreten! Der Datensatz wurde nicht erstellt");
                }
                catch (DbUpdateException ex)
                {
                    ModelState.AddModelError(string.Empty, "Es ist ein Fehler aufgetreten! Die Adress-Nummer ist bereits vergeben.");
                }              
            }
 
            return Json(new[] { adressen }.ToDataSourceResult(request, ModelState));
        }
 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete([DataSourceRequest] DataSourceRequest request, Adressen adressen)
        {
            Adressen Adressen = null;
 
            if (ModelState.IsValid)
            {
                Adressen = db.Adressen.Find(adressen.Eadr);
                db.Adressen.Remove(Adressen);
                db.SaveChanges();
            }
 
            return Json(new[] { adressen }.ToDataSourceResult(request, ModelState));
        }
 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit([DataSourceRequest] DataSourceRequest request, Adressen adressen)
        {
            if (adressen != null && ModelState.IsValid)
            {
                db.Entry(adressen).State = EntityState.Modified;
                db.Entry(adressen.BaLand).State = EntityState.Unchanged;
 
                try
                {
                    db.SaveChanges();
                }
                catch (InvalidOperationException ex)
                {
                    ModelState.AddModelError(string.Empty, "Es ist ein Fehler aufgetreten! Der Datensatz wurde nicht gespeichert");
                }
                catch (DbEntityValidationException ex)
                {
                    ModelState.AddModelError(string.Empty, "Es ist ein Fehler aufgetreten! Der Datensatz wurde nicht gespeichert");
                }
                catch (DbUpdateException ex)
                {
                    ModelState.AddModelError(string.Empty, "Es ist ein Fehler aufgetreten! Der Datensatz wurde nicht gespeichert");
                }   
            }
             
            return Json(new[] { adressen }.ToDataSourceResult(request, ModelState));
        }    
    }
Model for Adress
public partial class Adressen
    {
        public int Eadr { get; set; }
        public string Nama { get; set; }
        public string Namb { get; set; }
        public string Namc { get; set; }
        public string Namd { get; set; }
        public string Name { get; set; }
        public string Namf { get; set; }
        public string Pstc { get; set; }
        public string Ccty { get; set; }
 
        public virtual BaLand BaLand { get; set; }
    }
Model for Countries
public partial class BaLand
{
    public string Ccty { get; set; }
    public string Dsca { get; set; }
    public string Ictc { get; set; }
    public Nullable<short> Meec { get; set; }
    public string Tfcd { get; set; }
}

3 Answers, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 16 Oct 2013, 02:09 PM
Hi Helga,

 
Basically sorting / filtering / grouping of columns that are bound to a complex property from the model is not supported out-of-the-box as the Grid didn't have the information about which of the nested fields should be used for these operations. In current scenario I would suggest to flatter your model and use ForeignKeyColumn to match values from the column to their texts. Another option is to bind the column directly to the nested property as demonstrated below:

columns.Bound(p => p.Category.CategoryName);

Kind Regards,
Vladimir Iliev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Accepted
Helga
Top achievements
Rank 1
answered on 21 Oct 2013, 06:09 AM
Hello Vladimir,
thanks for your Help!
I've bound the Column directly to the nested Property an Sorting/Filtering etc is working.
columns.Bound(p => p.BaLand.Dsca).Title("Bezeichnung").ClientTemplate(" #= BaLand ? BaLand.Dsca : '' # ");
But now, my Custom Editor (Shared/EditorTemplates/BaLand.cshtml) isn't working. How should I name the EditorTemplate File?
@(Html.Kendo().DropDownList()
    .Name("BaLand")
    .BindTo((System.Collections.IEnumerable)TempData["Land"])
    .DataTextField("Dsca")
    .DataValueField("Ccty")
    .OptionLabel("Bitte wählen")
    .Events(e => e
        .Change("baland_change")
    )
)
Thanks for help
0
Helga
Top achievements
Rank 1
answered on 21 Oct 2013, 07:10 AM
Just found the solution. The UIHint: [UIHint("Dsca")].
Now, all is working perfect :)

Thanks
Tags
Grid
Asked by
Helga
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Helga
Top achievements
Rank 1
Share this question
or