Skip to content

Commit 895ac55

Browse files
implemented requested change
1 parent 84a59e1 commit 895ac55

File tree

3 files changed

+20
-40
lines changed

3 files changed

+20
-40
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
- Columns without buttons
2323
- In the columns component, when no button text is specified, no button is displayed (instead of an empty button)
2424
- New `unsafe_contents_md` property in the text component to allow rendering markdown with embedded HTML tags.
25-
- New `first_row_is_footer` property in table component. When enabled, the first row of table data will be put in the table footer instead of body.
26-
- New `freeze-footers` property in table component. If the is footer enabled, it will always be visible while the user scrolls the table body.
25+
- New `_sqlpage_footer` property for table rows. When applied, that row will be rendered as the table footer. It is recommended to use this on the last data row.
26+
- New `freeze_footers` property in table component. If the footer is enabled, this will make it always visible. Works similarly to `freeze_headers`.
2727

2828
## 0.33.1 (2025-02-25)
2929

examples/official-site/sqlpage/migrations/01_documentation.sql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -785,13 +785,15 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
785785
('empty_description', 'Text to display if the table does not contain any row. Defaults to "no data".', 'TEXT', TRUE, TRUE),
786786
('freeze_columns', 'Whether to freeze the leftmost column of the table.', 'BOOLEAN', TRUE, TRUE),
787787
('freeze_headers', 'Whether to freeze the top row of the table.', 'BOOLEAN', TRUE, TRUE),
788+
('freeze_footers', 'Whether to freeze the footer (bottom row) of the table, only works if that row has the `_sqlpage_footer` property applied to it.', 'BOOLEAN', TRUE, TRUE),
788789
('raw_numbers', 'Name of a column whose values are numeric, but should be displayed as raw numbers without any formatting (no thousands separators, decimal separator is always a dot). This argument can be repeated multiple times.', 'TEXT', TRUE, TRUE),
789790
('money', 'Name of a numeric column whose values should be displayed as currency amounts, in the currency defined by the `currency` property. This argument can be repeated multiple times.', 'TEXT', TRUE, TRUE),
790791
('currency', 'The ISO 4217 currency code (e.g., USD, EUR, GBP, etc.) to use when formatting monetary values.', 'TEXT', TRUE, TRUE),
791792
('number_format_digits', 'Maximum number of decimal digits to display for numeric values.', 'INTEGER', TRUE, TRUE),
792793
-- row level
793794
('_sqlpage_css_class', 'For advanced users. Sets a css class on the table row. Added in v0.8.0.', 'TEXT', FALSE, TRUE),
794795
('_sqlpage_color', 'Sets the background color of the row. Added in v0.8.0.', 'COLOR', FALSE, TRUE),
796+
('_sqlpage_footer', 'Sets this row as the table footer. It is recommended that this parameter is applied to the last row. Added in v0.34.0.', 'BOOLEAN', FALSE, TRUE),
795797
('_sqlpage_id', 'Sets the id of the html tabler row element. Allows you to make links targeting a specific row in a table.', 'TEXT', FALSE, TRUE)
796798
) x;
797799

@@ -808,11 +810,11 @@ INSERT INTO example(component, description, properties) VALUES
808810
{"icon": "timeline", "name": "[Chart](?component=chart)", "description": "Show graphs based on numeric data."}
809811
]')),
810812
('table', 'A sortable table with a colored footer showing the average value of its entries.',
811-
json('[{"component":"table", "sort":true, "first_row_is_footer":true}, '||
812-
'{"_sqlpage_color": "green", "Person": "Average", "Height": 180},' ||
813+
json('[{"component":"table", "sort":true}, '||
813814
'{"Person": "Rudolph Lingens", "Height": 190},' ||
814815
'{"Person": "Jane Doe", "Height": 150},' ||
815-
'{"Person": "John Doe", "Height": 200}]')),
816+
'{"Person": "John Doe", "Height": 200},' ||
817+
'{"_sqlpage_footer":true, "_sqlpage_color": "green", "Person": "Average", "Height": 180}]')),
816818
(
817819
'table',
818820
'A table with column sorting. Sorting sorts numbers in numeric order, and strings in alphabetical order.

sqlpage/templates/table.handlebars

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
{{#if description}}<caption class="text-center text-muted">{{description}}</caption>{{/if}}
3131
{{#each_row}}
3232
{{#if (eq @row_index 0)}}
33-
{{! Since we are inside the first data row, we always start with the header }}
33+
{{! Since we are inside the first data row, render the header }}
3434
<thead>
3535
<tr>
3636
{{#each this}}
@@ -54,17 +54,11 @@
5454
{{/each}}
5555
</tr>
5656
</thead>
57-
{{! For the first row we have two choices, depending on the first_row_is_footer variable }}
58-
{{#if ../first_row_is_footer}}
59-
{{! If first row is the footer we open the <tfoot> tag, while the <tbody> will be added after this row is rendered }}
60-
<tfoot>
61-
{{else}}
62-
{{! If there is no footer we open the <tbody> now, with a 'delay'ed closure }}
63-
<tbody class="table-tbody list">{{#delay}}</tbody>{{/delay}}
64-
{{/if}}
57+
<tbody class="table-tbody list">{{#delay}}</tbody>{{/delay}}
6558
{{~/if~}}
6659

67-
{{! Regardless of which row we are in, this part of the template renders the row data }}
60+
{{! If this data row should go into the footer, close the <tbody>, open the <tfoot> }}
61+
{{#if _sqlpage_footer}} </tbody><tfoot> {{/if}}
6862
<tr class="{{_sqlpage_css_class}} {{#if _sqlpage_color}}bg-{{_sqlpage_color}}-lt{{/if}}" {{#if _sqlpage_id}}id="{{_sqlpage_id}}"{{/if}}>
6963
{{~#each this~}}
7064
{{~#if (not (starts_with @key '_sqlpage_'))~}}
@@ -86,35 +80,19 @@
8680
{{~/each~}}
8781
</tr>
8882

89-
{{! After this <tr> has been rendered, we need to check again if there is more work to do done }}
90-
{{#if (eq @row_index 0)}}
91-
{{#if ../first_row_is_footer}}
92-
{{! If the first row was the footer, 2 things must happen: we need to close the <tfoot> tag }}
93-
</tfoot>
94-
{{! and since it was not done before, the <tbody> tag needs to be added now, with a delayed </tbody> }}
95-
<tbody class="table-tbody list">{{#delay}}</tbody>{{/delay}}
96-
{{/if}}
97-
{{~/if~}}
83+
{{! After this <tr> has been rendered, if this was a footer, we need to reopen a new <tbody> }}
84+
{{! No need for another delayed closure since the previous one still applies }}
85+
{{#if _sqlpage_footer}} </tfoot><tbody class="table-tbody list"> {{/if}}
9886
{{/each_row}}
9987
{{flush_delayed}}
10088

10189
{{! If not enough rows were rendered, we need to place a 'No data' cell. "Not enough rows" depends on the footer settings }}
102-
{{#if ../first_row_is_footer}}
103-
{{#if (lte @row_index 1)}}
104-
<tbody class="table-tbody list">
105-
<tr>
106-
<td class="text-center">{{default empty_description 'No data'}}</td>
107-
</tr>
108-
</tbody>
109-
{{/if}}
110-
{{else}}
111-
{{#if (eq @row_index 0)}}
112-
<tbody class="table-tbody list">
113-
<tr>
114-
<td class="text-center">{{default empty_description 'No data'}}</td>
115-
</tr>
116-
</tbody>
117-
{{/if}}
90+
{{#if (eq @row_index 0)}}
91+
<tbody class="table-tbody list">
92+
<tr>
93+
<td class="text-center">{{default empty_description 'No data'}}</td>
94+
</tr>
95+
</tbody>
11896
{{~/if~}}
11997
</table>
12098
</div>

0 commit comments

Comments
 (0)