Read only grid without paging
Computed columns whose value depends on several fields may be defined by adding a column with no asp-for
, ie not
connected to any property, but with just a name
.
Computed columns MUST have a custom display template that defines the way they combine the data item properties.
Clearly they can't have an edit template, so they are defined readonly. This way,
the display template is used also if the row is rendered in edit mode.
Since the column is not specific to any property the custom template receives the full item model
in Html.Item<T>()
.In the example below we removed the
price and currency columns, to add a computed column that combine them.
Name | Price | Av | |
---|---|---|---|
16G Tablet | 400.00$ | ||
1T High speed | 120.00€ | ||
1T SSD | 200.00€ | ||
3D Glasses | 400.00$ | ||
color laser printer | 400.00$ | ||
ink jet printer | 100.00$ | ||
laptop | 1200.00€ |
<grid asp-for="Products.Data" type="Immediate" all-properties="true" mvc-controller="typeof(LiveExamples.Controllers.GridsController)" row-id="readonly-example" operations="user => Functionalities.ReadOnly | Functionalities.ShowDetail" class="table table-condensed table-bordered"> <column asp-for="Products.Data.Element().Price" remove="true" /> <column asp-for="Products.Data.Element().ChosenCurrency" remove="true" /> <column name="fullprice" title="Price" priority="300" readonly="true"> <asp-template type="Display"> @{{ var Model = Html.Item<SimpleProductViewModel>(); <span>@Model.Price</span>@getEnumDisplayName(Model.ChosenCurrency) }} </asp-template> </column> </grid>
/* DetailWidthsAsString in ColumnLayout specifies percentage width for different device screen widths, while WidthsAsString percentage width when shown in-line within a collection control. Oder specify the order columns are rendered. Higher Order come first. All setting, included Display/Name may be overriden by providing a column definition TagHelper within the control definition. */ public class SimpleProductViewModel { public int? Id { get; set; } [MaxLength(128)] [ColumnLayout(DetailWidthsAsString = "100 50")] [Required] [Display(Name = "Name", Order = 400)] public string Name { get; set; } [ColumnLayout(DetailWidthsAsString = "60 30")] [Display(Name = "Price", Order = 300)] public decimal Price { get; set; } [Display(Name = "Cur", Order = 280)] [ColumnLayout(WidthsAsString = "10", DetailWidthsAsString = "40 20")] public Currency ChosenCurrency { get; set; } [ColumnLayout(DetailWidthsAsString = "20")] [Display(Name = "Av", Order = 230)] public bool Available { get; set; } } public class SimpleProductViewModelDetail: SimpleProductViewModel { [MaxLength(256)] [Display(Name = "Description", Order = 100)] [ColumnLayout(DetailWidthsAsString = "80")] [DisplayFormat(NullDisplayText = "no description available")] public string Description { get; set; } }
public async Task<IActionResult> ReadonlyComputed() { var model = new SimpleProductlistViewModel { Products = await Repository.GetPage<SimpleProductViewModel>( null, q => q.OrderBy(m => m.Name), 1, 20) }; return View(model); }