2525# '
2626# ' @inherit shared_params return
2727# '
28+ # ' @section Decorating `tm_t_crosstable`:
29+ # '
30+ # ' This module generates the following objects, which can be modified in place using decorators:
31+ # ' - `table` (`ElementaryTable` - output of `rtables::build_table`)
32+ # '
33+ # ' For additional details and examples of decorators, refer to the vignette
34+ # ' `vignette("decorate-modules-output", package = "teal")` or the [`teal_transform_module()`] documentation.
35+ # '
2836# ' @examplesShinylive
2937# ' library(teal.modules.general)
3038# ' interactive <- function() TRUE
@@ -134,7 +142,8 @@ tm_t_crosstable <- function(label = "Cross Table",
134142 show_total = TRUE ,
135143 pre_output = NULL ,
136144 post_output = NULL ,
137- basic_table_args = teal.widgets :: basic_table_args()) {
145+ basic_table_args = teal.widgets :: basic_table_args(),
146+ decorators = NULL ) {
138147 message(" Initializing tm_t_crosstable" )
139148
140149 # Requires Suggested packages
@@ -158,6 +167,7 @@ tm_t_crosstable <- function(label = "Cross Table",
158167 checkmate :: assert_multi_class(pre_output , c(" shiny.tag" , " shiny.tag.list" , " html" ), null.ok = TRUE )
159168 checkmate :: assert_multi_class(post_output , c(" shiny.tag" , " shiny.tag.list" , " html" ), null.ok = TRUE )
160169 checkmate :: assert_class(basic_table_args , classes = " basic_table_args" )
170+ checkmate :: assert_list(decorators , " teal_transform_module" , null.ok = TRUE )
161171 # End of assertions
162172
163173 # Make UI args
@@ -167,7 +177,8 @@ tm_t_crosstable <- function(label = "Cross Table",
167177 label = label ,
168178 x = x ,
169179 y = y ,
170- basic_table_args = basic_table_args
180+ basic_table_args = basic_table_args ,
181+ decorators = decorators
171182 )
172183
173184 ans <- module(
@@ -184,6 +195,7 @@ tm_t_crosstable <- function(label = "Cross Table",
184195
185196# UI function for the cross-table module
186197ui_t_crosstable <- function (id , x , y , show_percentage , show_total , pre_output , post_output , ... ) {
198+ args <- list (... )
187199 ns <- NS(id )
188200 is_single_dataset <- teal.transform :: is_single_dataset(x , y )
189201
@@ -221,7 +233,8 @@ ui_t_crosstable <- function(id, x, y, show_percentage, show_total, pre_output, p
221233 checkboxInput(ns(" show_percentage" ), " Show column percentage" , value = show_percentage ),
222234 checkboxInput(ns(" show_total" ), " Show total column" , value = show_total )
223235 )
224- )
236+ ),
237+ ui_teal_transform_data(ns(" decorate" ), transformators = args $ decorators )
225238 ),
226239 forms = tagList(
227240 teal.widgets :: verbatim_popup_ui(ns(" rcode" ), " Show R code" )
@@ -232,7 +245,7 @@ ui_t_crosstable <- function(id, x, y, show_percentage, show_total, pre_output, p
232245}
233246
234247# Server function for the cross-table module
235- srv_t_crosstable <- function (id , data , reporter , filter_panel_api , label , x , y , basic_table_args ) {
248+ srv_t_crosstable <- function (id , data , reporter , filter_panel_api , label , x , y , basic_table_args , decorators ) {
236249 with_reporter <- ! missing(reporter ) && inherits(reporter , " Reporter" )
237250 with_filter <- ! missing(filter_panel_api ) && inherits(filter_panel_api , " FilterPanelAPI" )
238251 checkmate :: assert_class(data , " reactive" )
@@ -351,7 +364,7 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
351364 teal.code :: eval_code(
352365 substitute(
353366 expr = {
354- lyt <- basic_tables %> %
367+ table <- basic_tables %> %
355368 split_call %> % # styler: off
356369 rtables :: add_colcounts() %> %
357370 tern :: analyze_vars(
@@ -387,19 +400,22 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
387400 substitute(
388401 expr = {
389402 ANL <- tern :: df_explicit_na(ANL )
390- tbl <- rtables :: build_table(lyt = lyt , df = ANL [order(ANL [[y_name ]]), ])
391- tbl
403+ table <- rtables :: build_table(lyt = table , df = ANL [order(ANL [[y_name ]]), ])
392404 },
393405 env = list (y_name = y_name )
394406 )
395407 )
396408 })
397409
410+ decorated_output_q_no_print <- srv_teal_transform_data(" decorate" , data = output_q , transformators = decorators )
411+ decorated_output_q <- reactive(within(decorated_output_q_no_print(), expr = table ))
412+
398413 output $ title <- renderText(output_q()[[" title" ]])
399414
400415 table_r <- reactive({
401416 req(iv_r()$ is_valid())
402- output_q()[[" tbl" ]]
417+ req(output_q())
418+ decorated_output_q()[[" table" ]]
403419 })
404420
405421 teal.widgets :: table_with_settings_srv(
@@ -409,7 +425,7 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
409425
410426 teal.widgets :: verbatim_popup_srv(
411427 id = " rcode" ,
412- verbatim_content = reactive(teal.code :: get_code(output_q( ))),
428+ verbatim_content = reactive(teal.code :: get_code(req(decorated_output_q() ))),
413429 title = " Show R Code for Cross-Table"
414430 )
415431
@@ -428,7 +444,7 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
428444 card $ append_text(" Comment" , " header3" )
429445 card $ append_text(comment )
430446 }
431- card $ append_src(teal.code :: get_code(output_q( )))
447+ card $ append_src(teal.code :: get_code(req(decorated_output_q() )))
432448 card
433449 }
434450 teal.reporter :: simple_reporter_srv(" simple_reporter" , reporter = reporter , card_fun = card_fun )
0 commit comments