Home
Products
Forums
Help
Publish Article

    Data formatting in GridView

    Download Sample MVC Grid Project

    GridView and/or DataGrid type of controls are one of the most commonly used controls in ASP.Net. Every new MVC project or ones being converted from old ASP.Net web form projects are going to need to figure out how to implement grid in MVC application. As part of conversion of a large project from ASP.Net Web Forms to MVC4, I had to do the same. There are some good articles and posts out there that describe how you can implement some basic grid view. When it comes to binding your MVC view to a complex model, then you will need to really understand how MVC framework translates post requests back into model that you used to bind the view.

    In this post I am going to show you some code that I used to create grid view in MVC application. In one of my previous posts I had discussed How to create GridView programmatically in code behind. That grid uses a model that consits of multiple list used to create editable grid view. I have implemented a MVC application that creates same grid view but with MVC framework.

    mvc grid view

    As you can see that grid view shows monthly sales data for different products. The grid allows a user to enter some numbers for each month's sales data block and then post is back to server. Following snippet shows how the model looks like.

    public class SalesGridViewModel
    {
      public List<SalesData> SalesData { get; set; }
      public List<SalesProduct> SalesProducts { get; set; }
      public List<SalesPeriod> SalePeriods { get; set; }
    }
        

    Naming of input fields is key

    The key to the whole puzzle of implementing an editable grid view is how you name each input or text box. MVC framework is smart enough to figure out how to interpret these names to recreate the model object and collections when form is posted back to server. There is a very good post ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries, that provides precise information that you need to understand how MVC framework translates the data and how you should names your fields. This is a must read post if you want to implement some complex grid views in MVC.

    Here is code snippet from my sample application that follows the recommendation of that post.

    @using (Html.BeginForm())
    {
      <table>
       <tr>
         <td> </td>
           @foreach (var priod in @Model.SalePeriods)
           {
            <td><div class="cellHeader">@priod.PeriodName</<div></td>
           }
           </tr>
           @for (int i = 0; i < Model.SalesData.Count; i++)
           {
            // Get product name.
            List<SalesProduct> productData = 
             (from product in Model.SalesProducts where 
              product.SalesProductId == Model.SalesData[i].ProductId select product).Take(1).
              ToList<SalesProduct>();
              <tr>
              <td>
            
             <input type="hidden" name="model.SalesData[@i].Id" value="@Model.SalesData[i].Id" />
             <input type="hidden" name="model.SalesData[@i].ProductId" value="@Model.SalesData[i].ProductId" />
             <div class="productNameCell">@productData[0].SalesProductName</div></td>
            
            @for (int j = 0; j < Model.SalesData[i].SalesInPeriod.Count; j++)
             {
               var thisPeriodSales = Model.SalesData[i].SalesInPeriod[j];
               var periodQuery = from period in Model.SalePeriods 
                 where period.PeriodId == thisPeriodSales.SalesPeriodId select period;
               var periodData = periodQuery.Take(1).ToList<SalesPeriod>()[0];
               <td>
               @{
               var panelID = string.Format("periodSales_{0}_{1}_{2}", 
                 thisPeriodSales.Id, Model.SalesData[i].ProductId, thisPeriodSales.SalesPeriodId);
               var periodSalesData = string.Format("{0}_{1}_{2}_{3}_{4}_{5}_{6}_{7}",
                   thisPeriodSales.Id,
                   productData[0].SalesProductName,
                   periodData.PeriodName,
                   thisPeriodSales.CurrentSales,
                   thisPeriodSales.UnitsSold,
                   thisPeriodSales.PendingSales,
                   thisPeriodSales.PendingUnits,
                   thisPeriodSales.ProjectedSales);
                   }
                   <div class="datadiv" id="@panelID" periodSalesData="@periodSalesData">
                   <table class="dataPanelTable">
                       <tr>
                           <td>
                               <img class="infoImg" src="@Url.Content("~/content/tip16_1.gif")" 
                            alt="" /><img class="infoImg" src="@Url.Content("~/content/warn16_1.gif")" alt="" />
                           </td>
                       </tr>
                       <tr>
                           <td><span>@thisPeriodSales.CurrentSales.Value.ToString("c")</span></td>
                       </tr>
                       <tr>
                           <td>
                               <input type="hidden" name="model.SalesData[@i].SalesInPeriod[@j].Id" 
                                value="@thisPeriodSales.Id" />
                               <input type="text" 
                               title="Please enter value between 1 between 5000" 
                               class="salesinput" 
                               name="model.SalesData[@i].SalesInPeriod[@j].CurrentSales" 
                               value="@thisPeriodSales.CurrentSales" />
                           </td>
                       </tr>
                   </table>
                   </div>
               </td>
             }
                    </tr>
                }
            </table>
            <div>
                <input type="submit" value="Submit" />
            </div>
    }
        

    Notice how all input elements have name attribute with name in a very specific format. This is most important part of the implementation. You may be wondering why hidden input fields have names following same convention as well. There is a strong reason for this. Since the model consists for embedded lists and enumeration, I need to know unique key field values associates at each level. This way when data is posted back to server when user hits Submit button, I can search for right set of data in lists.

    I post only the minimum amount of data to server that I will require to process submit requests. There is lot of data in model that is static. You can always get that data again on server side and repopulate your model with missing pieces of data.

    Sample Project

    I have attached my sample project that implements MVC GridView. There is some code in the view that is still not used but is there for next phase of implementation. In next phase I will refactor most of the code into some partial view and extension methods so it could be used at multiple places in my application.

    Go Freelance
    Home     About us     Contact us    Copyright    Privacy Policy    Return Policy    Advertisers
    Copyright © Netomatix