2929# '
3030# ' @inherit shared_params return
3131# '
32+ # ' @section Decorating `tm_data_table`:
33+ # '
34+ # ' This module generates the following objects, which can be modified in place using decorators:
35+ # ' - `table` ([DT::datatable()])
36+ # '
37+ # ' For additional details and examples of decorators, refer to the vignette
38+ # ' `vignette("decorate-modules-output", package = "teal")` or the [`teal_transform_module()`] documentation.
39+ # '
3240# ' @examplesShinylive
3341# ' library(teal.modules.general)
3442# ' interactive <- function() TRUE
@@ -96,7 +104,8 @@ tm_data_table <- function(label = "Data Table",
96104 ),
97105 server_rendering = FALSE ,
98106 pre_output = NULL ,
99- post_output = NULL ) {
107+ post_output = NULL ,
108+ decorators = NULL ) {
100109 message(" Initializing tm_data_table" )
101110
102111 # Start of assertions
@@ -121,6 +130,8 @@ tm_data_table <- function(label = "Data Table",
121130 checkmate :: assert_flag(server_rendering )
122131 checkmate :: assert_multi_class(pre_output , c(" shiny.tag" , " shiny.tag.list" , " html" ), null.ok = TRUE )
123132 checkmate :: assert_multi_class(post_output , c(" shiny.tag" , " shiny.tag.list" , " html" ), null.ok = TRUE )
133+
134+ checkmate :: assert_list(decorators , " teal_transform_module" , null.ok = TRUE )
124135 # End of assertions
125136
126137 ans <- module(
@@ -133,7 +144,8 @@ tm_data_table <- function(label = "Data Table",
133144 datasets_selected = datasets_selected ,
134145 dt_args = dt_args ,
135146 dt_options = dt_options ,
136- server_rendering = server_rendering
147+ server_rendering = server_rendering ,
148+ decorators = decorators
137149 ),
138150 ui_args = list (
139151 pre_output = pre_output ,
@@ -145,9 +157,7 @@ tm_data_table <- function(label = "Data Table",
145157}
146158
147159# UI page module
148- ui_page_data_table <- function (id ,
149- pre_output = NULL ,
150- post_output = NULL ) {
160+ ui_page_data_table <- function (id , pre_output = NULL , post_output = NULL ) {
151161 ns <- NS(id )
152162
153163 tagList(
@@ -185,7 +195,8 @@ srv_page_data_table <- function(id,
185195 variables_selected ,
186196 dt_args ,
187197 dt_options ,
188- server_rendering ) {
198+ server_rendering ,
199+ decorators ) {
189200 checkmate :: assert_class(data , " reactive" )
190201 checkmate :: assert_class(isolate(data()), " teal_data" )
191202 moduleServer(id , function (input , output , session ) {
@@ -238,7 +249,8 @@ srv_page_data_table <- function(id,
238249 ui_data_table(
239250 id = session $ ns(x ),
240251 choices = choices ,
241- selected = variables_selected
252+ selected = variables_selected ,
253+ decorators = decorators
242254 )
243255 )
244256 )
@@ -260,7 +272,8 @@ srv_page_data_table <- function(id,
260272 if_distinct = if_distinct ,
261273 dt_args = dt_args ,
262274 dt_options = dt_options ,
263- server_rendering = server_rendering
275+ server_rendering = server_rendering ,
276+ decorators = decorators
264277 )
265278 }
266279 )
@@ -270,7 +283,8 @@ srv_page_data_table <- function(id,
270283# UI function for the data_table module
271284ui_data_table <- function (id ,
272285 choices ,
273- selected ) {
286+ selected ,
287+ decorators ) {
274288 ns <- NS(id )
275289
276290 if (! is.null(selected )) {
@@ -282,6 +296,7 @@ ui_data_table <- function(id,
282296 tagList(
283297 teal.widgets :: get_dt_rows(ns(" data_table" ), ns(" dt_rows" )),
284298 fluidRow(
299+ ui_transform_teal_data(ns(" decorate" ), transformators = decorators ),
285300 teal.widgets :: optionalSelectInput(
286301 ns(" variables" ),
287302 " Select variables:" ,
@@ -305,7 +320,8 @@ srv_data_table <- function(id,
305320 if_distinct ,
306321 dt_args ,
307322 dt_options ,
308- server_rendering ) {
323+ server_rendering ,
324+ decorators ) {
309325 moduleServer(id , function (input , output , session ) {
310326 iv <- shinyvalidate :: InputValidator $ new()
311327 iv $ add_rule(" variables" , shinyvalidate :: sv_required(" Please select valid variable names" ))
@@ -314,27 +330,48 @@ srv_data_table <- function(id,
314330 ))
315331 iv $ enable()
316332
317- output $ data_table <- DT :: renderDataTable(server = server_rendering , {
318- teal :: validate_inputs(iv )
319-
333+ data_table_data <- reactive({
320334 df <- data()[[dataname ]]
321- variables <- input $ variables
322335
323336 teal :: validate_has_data(df , min_nrow = 1L , msg = paste(" data" , dataname , " is empty" ))
324337
325- dataframe_selected <- if (if_distinct()) {
326- dplyr :: count(df , dplyr :: across(dplyr :: all_of(variables )))
327- } else {
328- df [variables ]
329- }
338+ teal.code :: eval_code(
339+ data(),
340+ substitute(
341+ expr = {
342+ variables <- vars
343+ dataframe_selected <- if (if_distinct ) {
344+ dplyr :: count(dataname , dplyr :: across(dplyr :: all_of(variables )))
345+ } else {
346+ dataname [variables ]
347+ }
348+ dt_args <- args
349+ dt_args $ options <- dt_options
350+ if (! is.null(dt_rows )) {
351+ dt_args $ options $ pageLength <- dt_rows
352+ }
353+ dt_args $ data <- dataframe_selected
354+ table <- do.call(DT :: datatable , dt_args )
355+ },
356+ env = list (
357+ dataname = as.name(dataname ),
358+ if_distinct = if_distinct(),
359+ vars = input $ variables ,
360+ args = dt_args ,
361+ dt_options = dt_options ,
362+ dt_rows = input $ dt_rows
363+ )
364+ )
365+ )
366+ })
330367
331- dt_args $ options <- dt_options
332- if (! is.null(input $ dt_rows )) {
333- dt_args $ options $ pageLength <- input $ dt_rows
334- }
335- dt_args $ data <- dataframe_selected
368+ decorated_data_table_data <-
369+ srv_transform_teal_data(" decorate" , data = data_table_data , transformators = decorators )
336370
337- do.call(DT :: datatable , dt_args )
371+ output $ data_table <- DT :: renderDataTable(server = server_rendering , {
372+ req(data_table_data())
373+ teal :: validate_inputs(iv )
374+ decorated_data_table_data()[[" table" ]]
338375 })
339376 })
340377}
0 commit comments