knockout.jsmvccontribmvccontrib-grid

MVCContrib grid - Can I specify tbody attributes?


I'm trying to use MVCContrib grid together with KnockoutJS. To do this I have to specify data binding in tbody, e.g. <tbody data-bind="foreach: people">. I can't find the way how to do this.

@Html.Grid(Model).Attributes() applies my binding to <table> tag. Is there a way to set the tbody attribute?


Solution

  • The short answer is no, there is no way to set attributes on the tbody with the current implementation.

    But you can implement this functionality by yourself:

    You just need to implement your own version of the RenderBodyStart mothod from the GridRenderer class.

    There is alredy an implementation of the GridRenderer called HtmlTableGridRenderer what you can build on:

    public class BodyWithAttributesHtmlTableGridRenderer<T> 
        : HtmlTableGridRenderer<T> where T : class
        {
            private readonly IDictionary<string, object> bodyAttributes;
    
            public BodyWithAttributesHtmlTableGridRenderer(
                IDictionary<string, object> bodyAttributes)
            {
                this.bodyAttributes = bodyAttributes;
            }
    
            protected override void RenderBodyStart()
            {
                string str = BuildHtmlAttributes(bodyAttributes);
                if (str.Length > 0)
                    str = " " + str;
                RenderText(string.Format("<tbody{0}>", str));
            }
        }
    

    And in your view instead of calling Render() you can use the RenderUsing method where you can specify your custom renderer:

    @Html.Grid(Model))
        .RenderUsing(new BodyWithAttributesHtmlTableGridRenderer<MyModel>(
        new Dictionary<string, object>(){{"data-bind", "foreach: people"}}))
    

    And the generated html will look something like this:

    <table class="grid">
        <thead>
            <tr>
                <th>Prop</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: people">
            <tr class="gridrow">
                <td>1</td>
            </tr>
            <tr class="gridrow_alternate">
                <td>2</td>
            </tr>
        </tbody>
    </table>
    

    You should note this is just a quick and dirty solution to show what is possible and there are more extension points what you can use to make the attribute passing more nicer.