Rows

Rows are basically specifications on how to render a data item. Controls may usually have several Row definitions. The Row to render each specific data item is selected either based on the item run-time type (as a deatult) or based on a user provided row selection function. This function is a .net function for server controls (controls whose Html is created on the server side) and is a JavaScript function for client controls (controls whose html is created on the client side).

For server controls, as a default, for each data item its run-time type is compared with the type required by each row, starting from the last defined and moving up till a type compatible with the data item type is found. This process eventaully finds a compatible row since the 0 level row, called the main row has the same type of the property being rendered by the control (or of its item type in case of IEnumerables), that is the type all data item are subclass of.

row settings are specified by means of row-type tags contained in the control tag. However, the control tag itself acts as 0 level Row. More specifically, 0 Level row (called also the main row) attributes and content are taken care of by the control tag itself. In fact all control tags inerith from the row tag. Thus, in most of cases you will not use the row-type tag.

Each row-type (included the control tag itsel, that acts as a row-type) specifies all properties to be rendered by means of column tags it may have in its content. If a row-type specifies all-properties='true' all simple properties are rendered with default settings.

Default settings may be overriden by specifying a column tag for the property to customize. Moreover, a specific property may be removed by adding a column tag with remove='true'. Below, an example, where the same grid tag acts as main row and specifies all-properties='true', then two columns are removed and a new custom column is added.

<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>

Most of controls need to know wich property works as a principal key of the DTO/ViewModel. If a property is called "Id" it is automatically assumed to be the principal key. This, setting may be overriden by specifying the actual key property with the key attribute. When, all-properties='true' the key is assumed to be hidden. hidden properties either are not rendered at all, or are rendered in hidden fields, in case of server controls in edit-mode. This setting may be overwritten by specifying an explicit column tag for the principal key property.

Each row is rendered with a default template that depends on the control and on the Tag helper provider rendering it. The default template usually renders all properties specified either explicitely or by means of all-properties='true' with their own templates and insert the html obtained this way into a "row layout". For instance, in case of a "classical" table based grid the row layout is just a tr with a td for each column that is filled with the result returned by the column specific template invoked. Each row has both a display and an edit rendering modes, and each mode has its specific template.

Custom edit/display row templates may be provided either by overriding the default templates partial views as explained in the Templates section or by inserting an asp-template tag within the tag that defines the row (that, as already explained, is either the control tag itself or a specific row-type tag).

Row templates are passed a RowType options object, containing all row settings, that may be used to drive rendering. Each property may be rendered by invoking the RenderColumn method of this object. Methods and properties of RowType will be described later in this page.

row-type tag attributes

asp-for: ModelExpression
In the main row it specifies the collection or data item to render with the control. In a row-type tag it is:
  • SamePropertyInControlFor.Info().Model., in case row may be instantiated by any subclass of the compile-time item type
  • SamePropertyInControlFor.SubInfo<T>().Model., in case row may be instantiated only by the T subclass of the compile-time item type

Below an example of a control that specifies an additional row-type for a specific subclass of the item in the collection displaied by the ghrid:

...
...
<row-type asp-for="Products.Data.SubInfo<ProductMaintenanceViewModel>().Model"
          from-row="0">
    <column asp-for="Products.Data.Element().Price" colspan="1" />
    <column asp-for="Products.Data.SubElement<ProductMaintenanceViewModel>()
                        .MaintenanceYearlyRate" />
</row-type>
...
...

key: ModelExpression
The principal key property. If not specified a proprty with name "Id" is assumed.
all-properties: bool
When set, all simple properties of the data item are rendered(see discussion above).
operations: Func<IPrincipal, Functionalities>
A function that specifies the kind of operation to enable for the currently logges user. It defines all operations buttons to render (edit, detail edit, add, ...). Return value is an enum [Flag], whose values may be combined. Default function depends on the specific controt, but usually allow "all common" operations.
custom-buttons: bool
When set prevents automatic operation button generation based on the operations attrbute. In this case operation buttons must be rendered manually in a custom column according to the specification contained here.
from-row: uint?
When provided specifies a previously defined row where to import all column definitions. It is the index of the row-type definition. Main row has index 0, first row defined with row-type, has index 1, and so on. Inherited columns are dealt with as columns created with all-properties='true', that is, they may be removed and overwritten, and other columns may be added.
mvc-controller: Type
Contoller that performs all server operations required by the control on that row. Plase refer to the basic controllers documentation for more information.
row-id: string
Used together with mvc-controller. Name that identifies the row among all rows handled by the same controller. Plase refer to the basic controllers documentation for more information.
localization-type: Type
A type that when provided is used to create a localizer to localize all strings contained in the row templates (strings in buttons for instance). See here for more infos on how types are used for localization.
row-class, input-class, chekbox-class: string
Css classes to be added to the row root node, to all input tags, and to all checkboxes/radio buttons contained in the row. input-class, and chekbox-class may be overriden by analogous settings contained in each column.

Main methods, and properties of RowType object

All setting applied to row-type tag have corresponding properties in the RowType class. Developers coding custom templates are expected to use them in their custom templates. The RowType class has also other properties and helper methods that may be used when creating custom templates.

Columns: IEnumerable<Column>
All Columns corresponding to properties that must be rendered (not hidden).
async Task<IHtmlContent> RenderColumn(object rowModel, 
                    Column col, 
                    bool editMode, 
                    ContextualizedHelpers ctx)
                
Invoked in a custom template to render a Column contained in the Columns IEnumerable. rowModel is the data item passed to the row remplate, col the column, editMode specifies if the Column must be rendered in edit mode or in display mode, and finally ctx is a class that collects various helpers (HtmlHelper, ViewContext, etc.) that are needed by function based templates that cant take them from the View they are in as for all other templates. When you create a custom template; please create it and use it in the same way as the default template you are replacing.
int VisibleColumns(ContextualizedHelpers helpers, bool editOnly = false)
It returns the number of visible columns to render. When editOnly is set read only columns are excluded from the count.
bool MustAddButtonColumn(ContextualizedHelpers helpers, bool editOnly=false)
It verifies if a column with all selected operation buttons must be rendered. When editOnly is set the button for returning on display mode is not taken into account.
IHtmlContent RenderHiddens(ContextualizedHelpers ctx, object rowModel)
It renders all columns declared "hidden" with hidden input fields. Usefull only for edit templates of sever controls.
IHtmlContent RenderRowAttributes(object currentRow)
It renders all Html attributes needed for the row root Html node. Its usage is obligatory in all row templates. Below the root node of a grid row:

                <tr @row.RenderRowAttributes(Model)>
                ...
                ...
                ...
                </tr >
                
void ComputeWidths(bool edit, int gridMax)
It computes the number of grid "slots" to assign to each column in a grid system with gridMax slots (for instance, gridMax is 12 for the Bootstrap grid system). Each column contains a percentage specification for its desired width. All percentages are used to allocate all gridMax slots among all columns.Each column may specify percentages for the varius screen widths handled by the grid system. Slot allocation is computed for all screen widths specified. Read Column documentation for more infos on column widths. Usually, this computation is not carried out for table based rendering in which case percentages are used as they are. Results of the computation are available in the following properties of each Column:
                
        public int[] DisplayDetailWidths { get; set; }
        public int[] EditDetailWidths { get; set; }
                         
                
Arrays contain the number of allocated slots for each screen width, starting from the smaller one. Column widths may be spcified eiher with ColumnLayoutAttributes applied on data item properties or as attributes of the column tag. Specifications provided in column tag overrides ColumnLayoutAttributes specifications. If no percentage is specified, widths are not specified in table columns, and a 100% width is assumed in all other rendering modes. See here a live example containiing widths specifications both in data item and in the column tag.


Fork me on GitHub