I have a shiny app with a css style-sheet. Within the shiny app i use reactable and reactable.extras to capture text inputs.
library(shiny)
library(dplyr)
library(reactable)
library(reactable.extras)
df <- tibble(text_col = rep(NA, 5))
tweak_css <- function(file = "style.css") {
tags$link(rel= "stylesheet",
type = "text/css",
href = file) |>
tags$head()
}
shinyApp(
ui = fluidPage(
tweak_css(),
reactable_extras_dependency(),
reactableOutput("react"),
dataTableOutput("out")
),
server = function(input, output) {
rv <- reactiveValues(data = df)
output$react <- renderReactable({
reactable(
rv$data,
columns = list(
text_col = colDef(
cell = text_extra(id = "text",
class = "text-extra"))
)
)
})
text_d <- reactive({ input$text}) %>% debounce(3000)
observeEvent(text_d(), {
rv$data[text_d()$row, text_d()$column] <- text_d()$value
})
output$out <- renderDataTable({
rv$data
})
}
)
The accompanying style-sheet defines the size of the text input field. I fail to manage preventing text overflow.
.text-extra {
width: 80px;
height: 80px;
word-break: break-word;
}
I tried almost everything described here How to prevent text from overflowing in CSS? but it does not solve the problem. What can i do that the user can enter text with line breaks?
EDIT:
The use of DT seems not suitable since my original application has some more columns with checkboxes included.
What can i do that the user can enter text with line breaks?
You could wrap the text_extra
function and give it the correct style.
library(shiny)
library(dplyr)
library(reactable)
library(reactable.extras)
df <- tibble(text_col = rep(NA, 5))
text_extra <- function(id = NULL, class = NULL) {
function(value, index, name) {
div(
class = class,
style = "white-space: pre-wrap !important; word-break: break-all !important;",
textAreaInput(
inputId = paste0(id, "_", index, "_", name),
label = NULL,
value = value,
resize = "none",
width = "80px",
height = "80px"
)
)
}
}
shinyApp(
ui = fluidPage(
reactable_extras_dependency(),
reactableOutput("react"),
dataTableOutput("out")
),
server = function(input, output) {
rv <- reactiveValues(data = df)
output$react <- renderReactable({
reactable(
rv$data,
columns = list(text_col = colDef(cell = text_extra(id = "text", class = "text-extra")))
)
})
text_d <- reactive({ input$text}) %>% debounce(3000)
observeEvent(text_d(), {
rv$data[text_d()$row, text_d()$column] <- text_d()$value
})
output$out <- renderDataTable({
rv$data
})
}
)
library(shiny)
library(dplyr)
library(DT)
# Create sample data
df <- tibble(
text_col = rep(NA, 5),
yes_no = rep(FALSE, 5)
)
shinyApp(
ui = fluidPage(
DTOutput("table")
),
server = function(input, output, session) {
rv <- reactiveValues(data = df)
output$table <- renderDT({
datatable(
rv$data,
editable = list(
target = 'cell',
disable = list(columns = c(2)) # Enable editing for text column only
),
selection = "none",
options = list(
columnDefs = list(
list(
targets = 2, # yes_no column index (1-based)
render = JS("
function(data, type, row, meta) {
if (type === 'display') {
return '<input type=\"checkbox\"' +
(data ? ' checked' : '') +
' onclick=\"(' + function(el) {
var cell = el.parentNode;
var row = cell.parentNode;
var rowIdx = row.rowIndex;
var colIdx = cell.cellIndex;
Shiny.setInputValue(\'checkbox_click\',
{row: rowIdx, checked: el.checked, col: colIdx},
{priority: \'event\'}
);
} + ')(this)\">';
}
return data;
}")
)
)
)
)
})
observeEvent(input$table_cell_edit, {
info <- input$table_cell_edit
rv$data[info$row, info$col] <- info$value
})
observeEvent(input$checkbox_click, {
info <- input$checkbox_click
print(info)
rv$data$yes_no[info$row] <- info$checked # Add 1 because JS is 0-based
print(rv$data)
})
}
)