2

I create a table composed by 3 table like that: enter image description here

As you can see the Months data content is inside an horizontal scroll div, and it's work well. This is Odoo qweb engine but it's rendered as html...

.table-grid {
    width: 100% ;
    overflow-x: auto;
    white-space: nowrap;
    padding-bottom: 15px; /* Avoid scroll over data */
}

table, th, td {
    border: 1px solid black;
}

th, td {
    padding: .5em 1em;
}



<div class="table-grid">
    <table class="timesheet-table">
        <thead>
            <tr>
                <!-- Load month days columns -->
                <!-- record month_days is a n-upla like (week_day_name, day, month_name) -->
                <t t-foreach="month_days" t-as="day">
                    <th t-att-height="th_height">
                        <h5><div><t t-esc="day[0]"></t></div></h5>
                        <h6><t t-esc="day[2]"/> <t t-esc="day[1]"/></h6>
                    </th>
                </t>
            </tr>
        </thead>
        <tbody>
            <t t-foreach="range(projects_num)" t-as="project">
                <tr>
                    <t t-foreach="month_days" t-as="day">
                        <td>
                            00:00
                        </td>
                    </t>
                </tr>
            </t>
        </tbody>
    </table>
</div>

Is there a way to achieve this in a single table? So let scrollable only center content (less first column and last). I try to put the <div class="table-grid"> inside <tr> after some <td> but this doesn't work.

Here is the code that i try:

<table class="timesheet-table">
    <thead>
        <tr>
            <th t-att-height="th_height">Projects</th>
            <t t-foreach="month_days" t-as="day">
                <th t-att-height="th_height">
                    <h5><div><t t-esc="day[0]"></t></div></h5>
                    <h6><t t-esc="day[2]"/> <t t-esc="day[1]"/></h6>
                </th>
            </t>
            <th t-att-height="th_height">Totals</th>
        </tr>
    </thead>
    <tbody>
        <t t-foreach="range(projects_num)" t-as="project">
            <tr>
                <td>
                        Nome progetto
                </td>
                <div class="table-grid">
                    <t t-foreach="month_days" t-as="day">
                        <td>
                            00:00
                        </td>
                    </t>
                </div>
                <td>
                        45:00
                </td>
            </tr>
        </t>
    </tbody>
</table>

It's possible to achieve this in a single table?

Dario
  • 732
  • 7
  • 30
  • 2
    I would use datatables plugin - here is an example: https://datatables.net/extensions/fixedcolumns/examples/initialisation/left_right_columns.html – Pete Sep 19 '19 at 13:43
  • You may try accepted answer to question https://stackoverflow.com/questions/1312236/how-do-i-create-an-html-table-with-fixed-frozen-left-column-and-scrollable-body – Sergiy T. Sep 19 '19 at 14:33
  • @Pete i try with DataTable widget but i can't get fixed first left and first right column. I try with local istallation, i link all the necessary files but all table scroll. Fallowing this guides: https://datatables.net/download/ and your: https://datatables.net/extensions/fixedcolumns/examples/initialisation/left_right_columns.html Any idea? – Dario Sep 19 '19 at 15:38
  • @Pete "The reason for this is in how FixedColumns operates - the fixed columns are actually separate tables from the original DataTable (i.e. they are separate table elements) which are styled to look like they are visually part of the original table. These fixed tables are then positioned over the original DataTable." it's seems that it use more tables too? https://datatables.net/extensions/fixedcolumns/ – Dario Sep 20 '19 at 07:32

2 Answers2

1

Some alternatives

  1. Create 3 div and add a table inside each one, set a fixed width or a max-width on the middle div and use overflow-x: auto;

  2. Create a table with a row and 3 columns and add a table inside each one, set a fixed width or a max-width on the middle td of the parent tablet and use overflow-x: auto (this options is old school)

  3. Still using thead, tbody, tfoot, display them inline and set the table body as mid column and use overflow-x: auto;

Then your code will be like this:

table {
  border-collapse: collapse;
  border-spacing: 0;
  width: 215px;
}
thead, tbody, tfoot {
  display: table-cell;
}
thead, tfoot {
  width: 80px;
  padding-bottom: 16px;
}
tbody {
  display: block;
  table-layout: fixed;
  width: 100px;
  overflow-x: auto;
}
tr, td {
  border: 1px solid grey;
  width: 100%;
}
td {
  padding: 1rem;
  white-space: nowrap;
}
<table>
      <thead>
        <tr>
          <td>text</td>
        </tr>
        <tr>
          <td>text</td>
        </tr>
        <tr>
          <td>text</td>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
        </tr>
        <tr>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
        </tr>
        <tr>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
          <td>text text</td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <td>text</td>
        </tr>
        <tr>
          <td>text</td>
        </tr>
        <tr>
          <td>text</td>
        </tr>
      </tfoot>
    </table>

PS: Ignore the design, is horrible. Pay attention to the logic.

Rafael Perozin
  • 573
  • 7
  • 20
  • I would repeat my comment as I have made on the other answer that splits up the table: this is bad semantics - at this point you have stopped using tables for tabular data and started using it for layout – Pete Sep 19 '19 at 13:46
  • @Pete I particular prefer the third options that I gave. But I just think about it after rereading my answer. Do you agree? – Rafael Perozin Sep 19 '19 at 13:53
  • I would use js for this as re-styling tables will always lead to it not working correctly in different browsers especially when you are wanting fixed central columns - there's no easy way to do this with css only and keep the table semantically correct – Pete Sep 19 '19 at 13:56
  • This is like a solution that i have just used, i'm looking something for single table :D @Pete Sematinc wrong because it's like 90' css styling? :D – Dario Sep 19 '19 at 13:56
  • @Dario semantically wrong because your table is now split so if you came to it with a screen reader - it would not know the first table has anything to do with the second or third as they are completely separate – Pete Sep 19 '19 at 13:59
  • @Pete what you mean with screen reader? Like an html parser? (Just for a better knowledge) – Dario Sep 19 '19 at 14:20
  • @Dario I did with only one table. I used `display:table-cell` on the table to align the `thead/tbody/tfoot` inline and Unfortunately, the unique way that I found was using `display:block` on `tbody`. But this prevents to use JS. – Rafael Perozin Sep 19 '19 at 14:22
  • you cannot have multiple columns in the middle section with this edited structure – Pete Sep 19 '19 at 14:42
0

There is position: sticky property, but it bad browsers support.

I think you can use this hack with 3 tables in different <div> to reach necessary effect


Result

.container {
  position: relative;
  display: flex;
  align-items: flex-start;
}

.table-center {
  background: lightgoldenrodyellow;
  overflow-x: scroll;
}

.table-left,
.table-right {
  background: lightsteelblue;
}

table,
th,
td {
  border: 1px solid black;
}

th,
td {
  padding: .5em 1em;
}
<div class="container">
  <div class="table-left">
    <table>
      <tr>
        <th>Title</th>
      </tr>
      <tr>
        <td>Content</td>
      </tr>
      <tr>
        <td>Content</td>
      </tr>
    </table>
  </div>
  <div class="table-center">
    <table>
      <tr>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
        <th>Month</th>
      </tr>
      <tr>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
      </tr>
      <tr>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
        <td>00:00</td>
      </tr>
    </table>
  </div>
  <div class="table-right">
    <table>
      <tr>
        <th>Totals</th>
      </tr>
      <tr>
        <td>00:00</td>
      </tr>
      <tr>
        <td>00:00</td>
      </tr>
    </table>
  </div>
</div>

And same code on CodePen

enter image description here

hisbvdis
  • 1,376
  • 1
  • 8
  • 11