Search code examples
htmlasp.netasp.net-mvcrazorwebgrid

Add Multiple WebGrids with Styles in One Page without Redundancy


Basically, here's my code inside the view and I don't want to repeat WebGrid instances.

My Model

public class UsersWithDetailsModels
{
    public IEnumerable<ApplicationUser> ApplicationUsers { get; set; }
    public IEnumerable<PersonalInfo> PersonalInfos { get; set; }
    public IEnumerable<CreditHistory> CreditHistories { get; set; }
    public IEnumerable<Transaction> Transactions { get; set; }
}

My Controller

[AllowAnonymous]
public ActionResult Index(UsersWithDetailsModels model)
{
    return View(model);  // HERE: I can't get any data from database
}

Index.cshtml

@model IEnumerable<Lml.Models.UsersWithDetailsModels>

@{
    ViewBag.Title = "Home";
    Layout = null;

    // TABLE 1 with pager
    var pg = new WebGrid(Model, defaultSort: "Id", canPage: true, ajaxUpdateContainerId: "borrowersAppliedTable");
    pg.Pager(WebGridPagerModes.All);

    // TABLE 2 with pager
    var hg = new WebGrid(Model, defaultSort: "Id", canPage: true, ajaxUpdateContainerId: "borrowersAppliedAddressTable");
    hg.Pager(WebGridPagerModes.All);

    // TABLE 3 with pager
    var hg = new WebGrid(Model, defaultSort: "Id", canPage: true, ajaxUpdateContainerId: "borrowersAppliedMailingTable");
    hg.Pager(WebGridPagerModes.All);
}

You can obviously see how redundant it is.

Also, I have here the column styles

<!-- TABLE 1 -->
<div class="col-lg-6">
    <h2>Borrowers Applied</h2>
    <div class="table-responsive">
        @pg.GetHtml(
            htmlAttributes: new { id = "borrowersAppliedTable" },
            tableStyle: "table table-bordered table-hover table-striped",
            footerStyle: "table-footer text-center",
            columns:
                pg.Columns(
                    pg.Column(columnName: "Id", header: "Entry ID", format: (item) => item.GetSelectLink(item.Id.ToString())),
                    pg.Column(columnName: "DateApplied", header: "Entry Date"),
                    pg.Column(columnName: "FullName", header: "Full Name"),
                    pg.Column(columnName: "Email", header: "Email address")
            )
        )
    </div>
</div>

<!-- TABLE 2 -->
<div class="col-lg-6">
    <h2>Home Addresses</h2>
    <div class="table-responsive">
        @hg.GetHtml(
            htmlAttributes: new { id = "borrowersAppliedAddressTable" },
            tableStyle: "table table-bordered table-hover table-striped",
            footerStyle: "table-footer text-center",
            columns:
                hg.Columns(
                    hg.Column(columnName: "Id", header: "Entry ID", format: (item) => item.GetSelectLink(item.Id.ToString())),
                    hg.Column(columnName: "Street", header: "Street Address"),
                    hg.Column(columnName: "City", header: "City/Municipality"),
                    hg.Column(columnName: "Zip", header: "ZIP Code"),
                    hg.Column(columnName: "State", header: "Province/State"),
                    hg.Column(columnName: "Country")
        )) 
    </div>
</div>

<!-- TABLE 3 -->
<div class="col-lg-6">
    <h2>Mailing Addresses</h2>
    <div class="table-responsive">
        @hg.GetHtml(
            htmlAttributes: new { id = "borrowersAppliedMailingTable" },
            tableStyle: "table table-bordered table-hover table-striped",
            footerStyle: "table-footer text-center",
            columns:
                hg.Columns(
                    hg.Column(columnName: "Id", header: "Entry ID", format: (item) => item.GetSelectLink(item.Id.ToString())),
                    hg.Column(columnName: "MailStreet", header: "Street Address"),
                    hg.Column(columnName: "MailCity", header: "City/Municipality"),
                    hg.Column(columnName: "MailZip", header: "ZIP Code"),
                    hg.Column(columnName: "MailState", header: "Province/State"),
                    hg.Column(columnName: "MailCountry", header: "Country")
            )
        )
    </div>
</div>

As you can see these lines, I want to apply that on every table.

tableStyle: "table table-bordered table-hover table-striped",
footerStyle: "table-footer text-center",

I don't want to repeat that again and again.

Could anyone help me know the shortcut or is there any short and tidy method in displaying multiple WebGrids in one page?


Solution

  • One option would be to create configuration object for grids and loop through them to generate actual html:

    @model Lml.Models.UsersWithDetailsModels
    
    @{
        ViewBag.Title = "Home";
        Layout = null;
    
        var configs = new[]
        {
            new
            {
                Model = (IEnumerable<object>)Model.ApplicationUsers,
                Id = "borrowersAppliedTable",
                Header = "Borrowers Applied",
                Columns = new[]
                {
                    new {Name = "UserId", Header = "Entry ID"},
                    new {Name = "DateApplied", Header = "Entry Date"},
                    new {Name = "FullName", Header = "Full Name"},
                    new {Name = "Email", Header = "Email address"}
                }
            },
            new
            {
                Model = (IEnumerable<object>)Model.PersonalInfos,
                Id = "borrowersAppliedAddressTable",
                Header = "Home Addresses",
                Columns = new[]
                {
                    new {Name = "Id", Header = "Entry ID"},
                    new {Name = "Street", Header = "Street Address"},
                    new {Name = "City", Header = "City/Municipality"},
                    new {Name = "Zip", Header = "ZIP Code"},
                    new {Name = "State", Header = "Province/State"},
                    new {Name = "Country", Header = "Country"}
                }
            },
            new
            {
                Model = (IEnumerable<object>)Model.CreditHistories,
                Id = "borrowersAppliedMailingTable",
                Header = "Mailing Addresses",
                Columns = new[]
                {
                    new {Name = "Id", Header = "Entry ID"},
                    new {Name = "MailStreet", Header = "Street Address"},
                    new {Name = "MailCity", Header = "City/Municipality"},
                    new {Name = "MailZip", Header = "ZIP Code"},
                    new {Name = "MailState", Header = "Province/State"},
                    new {Name = "MailCountry", Header = "Country"}
                }
            },
            ...
        };
        var tables = configs.Select(config =>
        {
            var grid = new WebGrid(config.Model, defaultSort: config.Columns[0].Name, canPage: true, ajaxUpdateContainerId: config.Id);
            grid.Pager(WebGridPagerModes.All);
    
            return new { Id = config.Id, Grid = grid, Header = config.Header, Columns = config.Columns};
        });
    }
    
    @{
        foreach (var table in tables)
        {
            <div class="col-lg-6">
                <h2>@table.Header</h2>
                <div class="table-responsive">
                    @table.Grid.GetHtml(
                        htmlAttributes: new {id = table.Id },
                        tableStyle: "table table-bordered table-hover table-striped",
                        footerStyle: "table-footer text-center",
                        columns:
                            table.Grid.Columns(
                                table.Columns.Select((column, i) =>
                                {
                                    return i == 0
                                        ? table.Grid.Column(columnName: column.Name, header: column.Header, format: (item) => item.GetSelectLink(item.Id.ToString()))
                                        : table.Grid.Column(columnName: column.Name, header: column.Header);
                                }).ToArray())
                        )
                </div>
            </div>
        }
    }