4

I have a view that takes a List of objects.

So for example, if I had a List of people.. put in order by where they were located and the division they were in like so:

|  ID  |  Name  |  Location    |  Division  |          Age   |
--------------------------------------------------------------
    1     John      Building1      Finance              25
    2     Alex      Building1      Finance              30
    3     Chris     Building2      ISS                  22
    4     Justin    Building1      Human Resources      41
    5     Mary      Building2      Accounting           43 
    6     Ian       Building1      Human Resources      27
    7     John      Building1      Finance              35

So my action return statement looks like this:

lstOfPersonnel = lstOfPersonnel.OrderBy(x => x.Location).ThenBy(x => x.Division).ThenBy(x => x.Name).ToList();

return View(lstOfPersonnel);

In my View I have this:

<table class="table table-bordered no-border">
    @foreach (var item in Model)
    {
        if ((Model.IndexOf(item) == 0) || ((Model.IndexOf(item) != 0) && (!item.Building.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Building) || !item.Division.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Division))))
        {
                <thead>
                    <tr>
                        <th><b>@item.Building</b></th>
                        <th><b>@item.Division</b></th>
                    </tr>


                    <tr class="no-display"></tr>
                    <tr>
                        <th>Name</th>
                    </tr>
                    <tr>
                        <th>Age</th>
                    </tr>
                </thead>


                <tbody>
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Age)
                        </td>
                    </tr>
                </tbody>
        }
        else
        {
            <tbody>
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Age)
                    </td>
                </tr>
            </tbody>
        }
    }
</table>

Now, when I print preview this, it puts everybody that is in the same building and division under their respective header. However, the very first <thead> element.. lets say for this example would be Building1 and Finance due to the .OrderBy.... is shown on every page over top of the next Building.

So for a visual this is what it looks like when I print preview:

Page 1:

// Perfect Render
Building1 | Finance

Name    |    Age
Alex          30
John          35
John          25

Page 2:

// Repeat of Page 1's headers
Building1 | Finance

Name    |    Age

Building1 | Human Resources

Name    |    Age
Ian          27
Justin       41

Page 3:

// Repeat of Page 1's headers
Building1 | Finance

Name    |    Age

Building2 | Accounting

Name    |    Age
Mary         43

Page 4:

// Repeat of Page 1's headers
Building1 | Finance

Name    |    Age

Building2 | ISS

Name    |    Age
Chris         43
Grizzly
  • 5,873
  • 8
  • 56
  • 109
  • Which browser are you using? As far as I remember, Chrome has an issue printing headers on each page. I don't know if they fixed it yet. – manneJan89 Feb 24 '17 at 13:11
  • @jae.phoenix I am using IE 11. – Grizzly Feb 24 '17 at 13:12
  • I don't know if you already have, but take a look at this: [link](http://www.evagoras.com/2011/02/10/printing-table-headers-on-every-page/). As far as I understand the most important parts are adding the content you want printed on every page in a `thead` with the css you are using, and the content in the `tbody` with css `display:table-row-group;` – manneJan89 Feb 24 '17 at 13:21
  • @jae.phoenix I have edited my question to show a more specific example of my issue. – Grizzly Feb 24 '17 at 15:03
  • What if you do your for-loop outside of your table? so that it creates a new table every loop instead of just a head and a body. What I think is happening is that there are multiple theads inside the table, that is why it is printing each head on top of every page. – manneJan89 Feb 24 '17 at 15:11
  • @jae.phoenix tried, and the formatting goes up in flames.. maybe if you post code, I can try it – Grizzly Feb 24 '17 at 15:19
  • My C# is not that hot, but please check out my answer. – manneJan89 Feb 24 '17 at 15:33

2 Answers2

1

Try creating the table inside the for-loop, so that the loop creates a new table on every loop, instead of just the head and body. So I think this is happening:

<table>
    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>

    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>

instead of this

<table>
    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>
</table>

<table>
    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>
</table>

So what is happening is that you only have 1 table, and it is printing each head inside of that table at the top of each page, because the table is going over to the next page. With multiple tables, it only contains on head, so that head will print on top of a new page every time that table floats over to the next page.

You can then just do your if before every tbody because it looks like the head stays the same in every table.

Maybe try this:

        @foreach (var item in Model){

            <table class="table table-bordered no-border">

                <thead>
                    <tr>
                        <th><b>@item.Building</b></th>
                        <th><b>@item.Division</b></th>
                    </tr>


                    <tr class="no-display"></tr>
                    <tr>
                        <th>Name</th>
                    </tr>
                    <tr>
                        <th>Age</th>
                    </tr>
                </thead>

                <tbody>

                if ((Model.IndexOf(item) == 0) ||     ((Model.IndexOf(item) != 0) && (!item.Building.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Building) || !item.Division.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Division)))){   
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Age)
                        </td>
                    </tr>
                }
                else{
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Age)
                        </td>
                    </tr>
                }
                </tbody>

            </table>

        }
manneJan89
  • 1,004
  • 8
  • 27
  • The code you posted.. if I put the table inside the foreach loop.. that would create a new `thead` element for each item.. even if they are in the same building and division.. I only want 1 builiding and division per group of people. – Grizzly Feb 24 '17 at 15:35
  • what if you add an index to your `item` array inside the thead – manneJan89 Feb 24 '17 at 15:39
  • what do you mean? – Grizzly Feb 24 '17 at 15:39
  • Your `Model` is an array, and for each `item` in that array, you want to print a ``. So now inside your loop, you specify which item in the array to print. I think it should look something like this (not 100% sure): //this gets you both the item (item.value) and its index (item.i) @foreach (var item in Model((value,i) => new {i, value})) {
  • The index is @item.i and a value is @item.Building
  • } – manneJan89 Feb 24 '17 at 15:50
  • maybe you will understand it better. Take a look at this [link](http://stackoverflow.com/questions/10326406/getting-index-value-on-razor-foreach) – manneJan89 Feb 24 '17 at 15:51