This is not strictly a widget that you can readily use, but a template of sorts which you can import and modify as needed. It offers a generic data table with a few clues to help you figure out how you can suit it to your needs.
It will help you make a Framework7 data table that is responsive, that is, it will automatically convert to a list on narrower screens.
I have not seen it done before and it’s maybe something many could use. It also shows how you can use the latest features, like just using HTML tags as the component
or the @
prefixes for item states.
The Widget YAML
uid: data_table
tags: []
props:
parameters: []
parameterGroups: []
timestamp: May 9, 2023, 8:28:49 PM
component: div
config:
class:
- card
- data-table
- data-table-collapsible
- data-table-init
slots:
default:
- component: div
config:
class:
- card-header
slots:
default:
- component: div
config:
class:
- data-table-title
content: Nutrition
- component: table
config: {}
slots:
default:
- component: oh-repeater
config: {}
- component: thead
slots:
default:
- component: tr
slots:
default:
- component: th
config:
class:
- label-cell
content: Dessert (100g serving)
- component: th
config:
class:
- numeric-cell
content: Calories
- component: th
config:
class:
- numeric-cell
content: Fat (g)
- component: th
config:
class:
- numeric-cell
content: Carbs
- component: th
config:
class:
- numeric-cell
content: Protein (g)
- component: tbody
slots:
default:
- component: oh-repeater
config:
for: food
fragment: true
in:
- calories: 159
carbs: =@'ElectricityMeter_Power'
fat: "6.0"
name: Frozen Yoghurt
protein: "4.0"
- calories: 237
carbs: 37
fat: "9.0"
name: Ice Cream Sandwich
protein: "4.4"
- calories: 262
carbs: 24
fat: "16.0"
name: Eclair
protein: "6.0"
- calories: 305
carbs: 67
fat: "3.7"
name: Cupcake
protein: "4.3"
slots:
default:
- component: tr
slots:
default:
- component: td
config:
class:
- label-cell
content: =loop.food.name
data-collapsible-title: Dessert
- component: td
config:
class:
- numeric-cell
content: =loop.food.calories
data-collapsible-title: Calories
- component: td
config:
class:
- numeric-cell
data-collapsible-title: Fat (g)
slots:
default:
- component: span
config:
visible: =loop.food.fat < 10
content: =loop.food.fat
- component: f7-chip
config:
visible: =loop.food.fat >= 10
color: red
text: =loop.food.fat
icon-f7: exclamationmark_triangle_fill
style:
font-size: var(--f7-table-body-font-size)
- component: td
config:
class:
- numeric-cell
content: =loop.food.carbs
data-collapsible-title: Carbs
- component: td
config:
class:
- numeric-cell
content: =loop.food.protein
data-collapsible-title: Protein (g)
How to change
This is offered as a card but if you want to integrate it to another widget you can remove the card
class from the root component, as well as the first div component under the default slot to remove the “Nutrition” header:
The columns are defined in two places, first under the thead
component (for the headers):
- component: thead
slots:
default:
- component: tr
slots:
default:
- component: th
config:
class:
- label-cell
content: Dessert (100g serving)
- component: th
config:
class:
- numeric-cell
content: Calories
- component: th
config:
class:
- numeric-cell
content: Fat (g)
- component: th
config:
class:
- numeric-cell
content: Carbs
- component: th
config:
class:
- numeric-cell
content: Protein (g)
The label-cell
and numeric-cell
classes determine the alignment. Note that you can also use classes like xsmall-only
, small-only
, medium-only
, large-only
, xlarge-only
to display columns only when the screen is large enough.
To build the table’s body we use a oh-repeater
directly under the tbody
HTML tag:
- component: tbody
slots:
default:
- component: oh-repeater
config:
for: food
fragment: true
in:
- calories: 159
carbs: =@'ElectricityMeter_Power'
fat: "6.0"
name: Frozen Yoghurt
protein: "4.0"
- calories: 237
carbs: 37
fat: "9.0"
name: Ice Cream Sandwich
protein: "4.4"
- calories: 262
carbs: 24
fat: "16.0"
name: Eclair
protein: "6.0"
- calories: 305
carbs: 67
fat: "3.7"
name: Cupcake
protein: "4.3"
In this case we feed it an array of objects with several properties (the in:
parameter of the oh-repeater
). Note how it can include expressions (the “carbs” property of the Frozen Yoghurt was changed to an expression which uses the state of the ElectricityMeter_Power
item by employing the @
operator).
In the default slot of the oh-repeater
we define the repeated rows and columns:
slots:
default:
- component: tr
slots:
default:
- component: td
config:
class:
- label-cell
content: =loop.food.name
data-collapsible-title: Dessert
- component: td
config:
class:
- numeric-cell
content: =loop.food.calories
data-collapsible-title: Calories
- component: td
config:
class:
- numeric-cell
data-collapsible-title: Fat (g)
slots:
default:
- component: span
config:
visible: =loop.food.fat < 10
content: =loop.food.fat
- component: f7-chip
config:
visible: =loop.food.fat >= 10
color: red
text: =loop.food.fat
icon-f7: exclamationmark_triangle_fill
style:
font-size: var(--f7-table-body-font-size)
- component: td
config:
class:
- numeric-cell
content: =loop.food.carbs
data-collapsible-title: Carbs
- component: td
config:
class:
- numeric-cell
content: =loop.food.protein
data-collapsible-title: Protein (g)
Note the two options used here. Most columns just define a td
with a content
config property, and the appropriate classes and other properties (data-collapsible-title
is used when the table is collapsed to a label/value list as shown above, the value in that property will be the label).
For the Fat (g) column, however, we have this:
- component: td
config:
class:
- numeric-cell
data-collapsible-title: Fat (g)
slots:
default:
- component: span
config:
visible: =loop.food.fat < 10
content: =loop.food.fat
- component: f7-chip
config:
visible: =loop.food.fat >= 10
color: red
text: =loop.food.fat
icon-f7: exclamationmark_triangle_fill
style:
font-size: var(--f7-table-body-font-size)
We have defined a default slot for the td
(table cell) with 2 components that will be alternatively displayed if the fat property of the current item in the array that acts as a source to the oh-repeater
is below or above 10 (using the visible
property).
The two alternatives are a span
component (which is maybe the simplest HTML tag and will just insert the text into the cell), or a f7-chip
component when the value is higher or equal than 10, which will render with a rounded red backdrop and associated icon. We also redefine the font size with the CSS variable used for table cells (see https://www.openhab.org/docs/ui/building-pages.html#css-variables)
Changelog
Version 0.1
- initial release