create a HTML5 Table with variable column count

2
Hi there, We are working with very generic data. We would like to display this data in a table. Our data could look like this [ { "a": 1, "b": true }, { "a": 2, "b": false } ] or like this [ { "c": "some string", "d": 123, "e": true, "f": "2020-02-02T0202" }, { "c": "another string", "d": 234, "e": false, "f": "2020-03-02T0202" } ] or any other structure imaginable. In Mendix this setup would be like so: List of Entity Entity: - List of Attribute Attribute: - Name - Value So what we need to do is convert rows into columns by converting the List of Attributes of each Entity into columns. We currently use a method where we loop over each Entity and generate a wrapper container with display: flex. We then loop over each Attribute within it and generate a flex box in order to align it horizontally.  This works, but the issue we have now is when the content is not the same width (which is most of the time) the simulated columns start to spread (e.g. like so ), because they are of course not constraint vertically in any way. I tried to work with CSS min-width and max-width in order to force the width to be the same. This works but is not suitable for less columns because it doesn’t make use of the available space. The best option I figured would be to use a plain old table for this. Declare the table with its headers. Then loop over each Entity and generate a tr-wrapper, within it loop over each Attribute and generate a td-block in order to dynamically generate the desired table looking somewhat like this: But how do I do this? Mendix generates a lot of overhead and wrapping divs and a I wasn’t able to find a way of extending the available render modes for containers (in settings.json?). Any ideas?
asked
4 answers
2

Instead of flex you can use css-grid. See this post for more details – https://www.notion.so/gajduk/The-road-to-responsive-tables-in-Mendix-f8a1de4595634167bd489c48b565fbe1#603b090295a8464bb2d4f760e9b5e2ac

answered
2

During my research I came across the css property “display: contents;”. 

from the mozilla documentation

These elements don't produce a specific box by themselves. They are replaced by their pseudo-box and their child boxes.

This allows me (at least in a test setup) to ignore wrapping divs and enforce a table layout through css.

Having a HTML structure like the following: 

<div class="mx-templategrid">
    <div class="mx-grid-content">
        <!-- Table -->
        <div class="mx-templategrid-content-wrapper">
            <!-- Table-Row -->
            <div class="mx-templategrid-row">
                <div class="mx-templategrid-item">
                    <div class="mx-dataview">
                        <div class="mx-dataview-content">
                            <div>
                                <div class="mx-listview">
                                    <ul>
                                        <!-- Table-Cell -->
                                        <li> ... </li>
                                        <!-- Table-Cell -->
                                        <li> ... </li>
                                        <!-- Table-Cell -->
                                        <li> ... </li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!-- Table-Row -->
            <div class="mx-templategrid-row">
                <div class="mx-templategrid-item">
                    <div class="mx-dataview">
                        <div class="mx-dataview-content">
                            <div>
                                <div class="mx-listview">
                                    <ul>
                                        <!-- Table-Cell -->
                                        <li> ... </li>
                                        <!-- Table-Cell -->
                                        <li> ... </li>
                                        <!-- Table-Cell -->
                                        <li> ... </li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

 I was able to reproduce the table layout with the following css:

.mx-templategrid-content-wrapper {
    display: table;
}

.mx-templategrid-row {
    display: table-row;
}

.mx-listview>ul>li {
    display: table-cell;
}

.mx-listview>ul,
.mx-listview,
.mx-dataview-content>div,
.mx-dataview-content,
.mx-dataview,
.mx-templategrid-item {
    display: contents;
}

Unfortunately we have to be backwards compatible until Edge v43, with which it is not supported

Also, it seems to be very experimental...

Appendix B: Effects of display: contents on Unusual Elements
This section is (currently) non-normative.

Some elements aren’t rendered purely by CSS box concepts; for example, replaced elements (such as img), many form controls (such as input), and SVG elements.

… therefor I am not sure if this is really a valid approach, but it is a solution for the of Mendix generated wrapping divs, which can be a pain to work with when styling the app.

 

Maybe this is viable for some cases. I thought I’d let you guys know.

I still haven’t found another good approach in order to create a dynamic amount of columns and rows.

answered
1

If each table has the same amount of rows, it should be achievable using flex using properties flex-grow 1 and flex-basis 0:

https://codepen.io/Gabeler/pen/YzXNgdw

 

answered
0

the easiest way would be to keep using flex.

figure out what width you want each colom to be and right some css like


listviewModifierClass{
  &.mx-listview>ul>li {
    &nth:child(1){
      width: 100px
    }
    &nth:child(2){
      width: 50px
    }
    &nth:child(3){
      width: 30px
    }
    &nth:child(4){
      width: 120px
    }
  }
}

its not super dynamic, but it is probably easiest to understand conceptually and is often good enough for most scenarios :D 

answered