8
votes

I have sql table with fields: Id, Field1, Field2, Field3, Field4, Field5 and I have other table with column f1,f2,f3,f4,f5 this table have only one row with this data: code, vendor, model, year, price

I have this model in my project

public class Products
{
  [ScafoldColumn(false)]  
  public Guid Id{get;set;}
  public string Field1{get;set;}
  public string Field2{get;set;}
  public string Field3{get;set;}
  public string Field4{get;set;}
  public string Field5{get;set;}
}

And I want than my kendo grid show column header not like Field1... but Like data in table 2(code, vendor, model, year, price) how can I load this data from table and set to kendo grid column header?

6

6 Answers

14
votes

I'm not sure if what your asking can be done. But the Kendo Grid has a title property, so you can set the Header to whatever you please.

@(Html.Kendo().Grid<OMSWeb.Models.OrderGridViewModel>()
 .Name("grid")
.HtmlAttributes(new { style = "width:115%;font-size:10px;line-height:2em" })
.Columns(columns =>
{        
    columns.Bound(m => m.AdvertiserName).Title("Advertiser Name");
});

etc.
2
votes

You can't actually do what you are trying. You can bind your model like the following and use Title() as #C Sharper says:

@(Html.Kendo().Grid<Models.Products>()
  .Name("YourReportName")
  .Resizable(resizing => resizing.Columns(true))
  .Columns(columns =>
    {
    columns.Bound(p => p.ID).Width(50).Title("ID");
    columns.Bound(p => p.Field1).Width(50).Title("f1");
    columns.Bound(p => p.Field2).Width(50).Title("f2");
    columns.Bound(p => p.Field3).Width(50).Title("f3");
    columns.Bound(p => p.Field4).Width(50).Title("f4");
    columns.Bound(p => p.Field5).Width(50).Title("f5");
    })
  .Scrollable()
  .DataSource(dataSource => dataSource.Ajax()
    .Read(read => read.Action("GetModelData", "Home")))
  .Pageable(pager => pager.Refresh(true))
  .Sortable()
)

It should be achievable if you bind your grid with js and accept JSon and if you want your column name should be Database driven. In code behind you just need convert your object to json with JsonConvert.SerializeObject(Products); and get the required column names from DB, replace "Field1", "Field2" etc with "f1", "f2" etc. Hope this helps. If you need further assistance please leave a comment. Thanks.

2
votes

Thanks for answers. But I found other solution I create class

public class MyMetadataProvider : AssociatedMetadataProvider
{
    public MyMetadataProvider () : base()
    {
    }

    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType,
                                                    string propertyName)
    {
        var metaData = new ModelMetadata(this, containerType, modelAccessor, modelType, propertyName);

        if (propertyName == null)
            return metaData;
        if (propertyName.StartsWith("Field"))
        {
            var c = DbHelper.GetProductColumns();//get data from database
            if (c.Count == 1)
            {
                if (c != null && propertyName == "Field1")
                    metaData.DisplayName = c[0].F1;
                if (c != null && propertyName == "Field2")
                    metaData.DisplayName = c[0].F2;
                if (c != null && propertyName == "Field3")
                    metaData.DisplayName = c[0].F3;
                if (c != null && propertyName == "Field4")
                    metaData.DisplayName = c[0].F4;
                if (c != null && propertyName == "Field5")
                    metaData.DisplayName = c[0].F5;
            }
        }
        else
        {
            if (attributes != null)
            {
                foreach (var a in attributes)
                {
                    var type = a.TypeId as Type;
                    if (type != null && type.Name == "DisplayNameAttribute")
                    {
                        var dn = (a as DisplayNameAttribute).DisplayName;
                        if (!string.IsNullOrEmpty(dn))
                            metaData.DisplayName = dn;

                    }
                }
            }
        }
        return metaData;
    }


}

Use this metadata provider I can change any grid in my website without any additional JS code. I hope this helps someone else. Thanks again.

2
votes

Use your model if it is available. like this

@Html.Kendo().Grid(Model.Records).Name("ProfessionalScheduleGrid").Columns(x=>
    {
        x.Bound(item => item.Staff.User.Email).Title("Email");
        x.Bound(item => item.Discipline.Name).Title("Discipline");
        x.Bound(item => item.Day1Activity.Activity.Code).Title(Model.SelectedSchedule.ScheduleDays.OrderBy(y => y.DayNumber).Where(y => y.DayNumber == 1).First().Day.ToString("ddd(dd)"));
        x.Bound(item => item.Day2Activity.Activity.Code).Title(Model.SelectedSchedule.ScheduleDays.OrderBy(y => y.DayNumber).Where(y => y.DayNumber == 2).First().Day.ToString("ddd(dd)"));
        x.Bound(item => item.Day3Activity.Activity.Code).Title(Model.SelectedSchedule.ScheduleDays.OrderBy(y => y.DayNumber).Where(y => y.DayNumber == 3).First().Day.ToString("ddd(dd)"));
        x.Bound(item => item.Day4Activity.Activity.Code).Title(Model.SelectedSchedule.ScheduleDays.OrderBy(y => y.DayNumber).Where(y => y.DayNumber == 4).First().Day.ToString("ddd(dd)"));
        x.Bound(item => item.Day5Activity.Activity.Code).Title(Model.SelectedSchedule.ScheduleDays.OrderBy(y => y.DayNumber).Where(y => y.DayNumber == 5).First().Day.ToString("ddd(dd)"));
        x.Bound(item => item.EntireWeekActivity).Title("Set Entire Week");
}).Sortable().Filterable().Pageable().Selectable().DataSource(dataSource => dataSource.Server().Model(model => model.Id(p => p.Id)))
1
votes

Hey I have done the same in kendo grid generated through Jquery.

Step 1: Create a array from the data of the second table(code, vendor, model, year, price).

Step 2: Build a ColumnList such that the 'field' property of it's objects are pointing to your Table 1 and the 'title' will be taken from the array elements that we created.

Step 3: Assign this columnList to your kendo columns property.

Only thing to watch is that the number of columns in both the tables should be equal.

0
votes

As answered in this post... http://www.somedave.com/posts/automatically-generating-column-titles-for-a-kendoui-mvc-grid

To use:

columns.Bound(p => p.YourField).DisplayNameTitle();

Add code:

public static GridBoundColumnBuilder<TModel> DisplayNameTitle<TModel>(
this GridBoundColumnBuilder<TModel> builder) where TModel : class, new()
{
    // Create an adapter to access the typed grid column
    // (which contains the Expression)
Type adapterType = typeof(GridBoundColumnAdapter<,>)
    .MakeGenericType(typeof(TModel), builder.Column.MemberType);
IGridBoundColumnAdapter adapter =
    (IGridBoundColumnAdapter)Activator.CreateInstance(adapterType);

// Use the adapter to get the title and set it
return builder.Title(adapter.GetDisplayName(builder.Column));
}

private interface IGridBoundColumnAdapter
{
    string GetDisplayName(IGridBoundColumn column);
}

private class GridBoundColumnAdapter<TModel, TValue>
: IGridBoundColumnAdapter where TModel : class, new()
{
    public string GetDisplayName(IGridBoundColumn column)
    {
    // Get the typed bound column
    GridBoundColumn<TModel, TValue> boundColumn =
        column as GridBoundColumn<TModel, TValue>;
    if (boundColumn == null) return String.Empty;

    // Create the appropriate HtmlHelper and use it to get the display name
    HtmlHelper<TModel> helper = HtmlHelpers.For<TModel>(
        boundColumn.Grid.ViewContext,
        boundColumn.Grid.ViewData,
        new RouteCollection());
    return helper.DisplayNameFor(boundColumn.Expression).ToString();
    }
}