Delete the row in DT table shiny - r

I am trying to delete the row in the table below but not able to . Can anyone please guide me here.
The row should get deleted when the user selects the row and then clicks on action button
library(shiny)
library(httr)
library(jsonlite)
library(readxl)
library(DT)
library(glue)
ui <- fluidPage({
au <- read_excel("au.xlsx")
au <- as.data.frame(au)
df <- reactiveValues(asd = NULL)
mainPanel(
dataTableOutput("ir"),
actionButton("ac", "ac")
)
})
server <- function(input, output, session) {
output$ir <- renderDataTable({
df$asd <- head(iris)
datatable(df$asd)
})
observeEvent(input$ac,{
# browser()
df$asd <- df$asd[-c(as.numeric(input$ir_rows_selected)),]
})
}
shinyApp(ui, server)

Here is the way using a Shiny button:
library(shiny)
library(DT)
ui <- fluidPage(
actionButton("delete", "Delete selected row"),
br(),
DTOutput("tbl")
)
server <- function(input, output, session){
output[["tbl"]] <- renderDT({
datatable(iris[1:5,],
callback = JS(c(
"$('#delete').on('click', function(){",
" table.rows('.selected').remove().draw();",
"});"
))
)
}, server = FALSE)
}
shinyApp(ui, server)
And here is the way using a button integrated in the DT table:
library(shiny)
library(DT)
ui <- fluidPage(
br(),
DTOutput("tbl")
)
server <- function(input, output, session){
output[["tbl"]] <- renderDT({
datatable(iris[1:5,],
extensions = 'Buttons',
options = list(
dom = 'Bfrtip',
buttons = list(
list(
extend = "collection",
text = "Delete selected row",
action = DT::JS(c(
"function ( e, dt, node, config ) {",
" dt.rows('.selected').remove().draw();",
"}"))
)
)
)
)
}, server = FALSE)
}
shinyApp(ui, server)
With these methods, the table is not re-rendered when the row is deleted.

Related

Another datatable inside the main datatable

IS there a way to get datatable when the user clicks on the row. Basically when the user clicks on any row, the last 4 columns of that specific row should be displayed in a modal (in datatable format)
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("mydatatable")
)
server <- function(input, output, session) {
mycars = head(mtcars)
output$mydatatable = DT::renderDataTable(mycars, selection = 'single',
rownames = FALSE, options = list(dom = 't'))
observeEvent(input$mydatatable_rows_selected,
{
showModal(modalDialog(
title = "You have selected a row!",
mycars[input$mydatatable_rows_selected,]
))
})
}
shinyApp(ui, server)
You can use renderDataTable inside modalDialog.
library(shiny)
library(DT)
ui <- fluidPage(
DT::dataTableOutput("mydatatable")
)
server <- function(input, output, session) {
mycars = head(mtcars)
output$mydatatable = DT::renderDataTable(mycars, selection = 'single',
rownames = FALSE, options = list(dom = 't'))
observeEvent(input$mydatatable_rows_selected,
{
showModal(modalDialog(
title = "You have selected a row!",
DT::renderDataTable({
DT::datatable(mycars[input$mydatatable_rows_selected, (ncol(mycars) - 3):ncol(mycars)])
})
))
})
}
shinyApp(ui, server)

data table disappear after editing in shiny app

I'm trying to make an editable and downloadable data table in shiny app. After I edit the table, the data table automatically disappear for some reason. This only happen when the data dat is reactive (which is necessary in my app).
Does anyone knows what is going on? Thanks a lot.
example code below:
library(shiny)
library(DT)
ui <- fluidPage(
selectInput("nrow",
"num of rows",
choices = 1:5,
selected = 3,
multiple = FALSE),
DTOutput("table")
)
server <- function(input, output){
dat = reactive({
iris[1:as.integer(input$nrow),]
})
output[["table"]] <- renderDT({
datatable(dat(), editable = "cell", extensions = "Buttons",
options = list(
dom = "Bfrtip",
buttons = list(
"csv"
)
))
})
observeEvent(input[["table_cell_edit"]], {
cellinfo <- input[["table_cell_edit"]]
dat() <<- editData(dat(), input[["table_cell_edit"]], "table")
})
}
shinyApp(ui, server)
Try this:
library(shiny)
library(DT)
ui <- fluidPage(
selectInput("nrow","num of rows",choices = 1:5,selected = 3,multiple = FALSE),
DTOutput("table")
)
server <- function(input, output){
v <- reactiveValues()
observeEvent(input$nrow,{
v$dat <- iris[1:as.integer(input$nrow),]
})
output[["table"]] <- renderDT({
datatable(v$dat, editable = "cell", extensions = "Buttons", options = list(dom = "Bfrtip",buttons = list("excel")))
})
observeEvent(input[["table_cell_edit"]], {
cellinfo <- input[["table_cell_edit"]]
v$dat <<- editData(v$dat, input[["table_cell_edit"]], "table")
})
}
shinyApp(ui, server)
Is it OK like this ? A possible unwanted behavior is that the table is reset after changing the number of rows. But I don't think we can avoid that... since these are two different tables.
library(shiny)
library(DT)
ui <- fluidPage(
selectInput("nrow",
"num of rows",
choices = 1:5,
selected = 3,
multiple = FALSE),
DTOutput("table")
)
server <- function(input, output){
dat0 <- iris
dat <- reactiveVal()
observe({
dat(dat0[1:as.integer(input$nrow),])
})
output[["table"]] <- renderDT({
datatable(dat(), editable = "cell", extensions = "Buttons",
options = list(
dom = "Bfrtip",
buttons = list(
"csv"
)
))
})
observeEvent(input[["table_cell_edit"]], {
cellinfo <- input[["table_cell_edit"]]
dat(editData(dat(), input[["table_cell_edit"]], "table"))
})
}
shinyApp(ui, server)

RShiny: DT select rows and assign to group

I would like to give users an option to assign different rows (subjects) to groups.
Ideally, one can highlight rows, then write a group name in the "Assign to group: " field and it is saved. Then they can select a new set of rows and add those to a different group; and so on until all desired rows are assigned.
Here is what I have so far. I can't figure out how to save the results before selecting a new set of rows..
library(shiny)
library(DT)
ui <- fluidPage(
fluidRow(
column(6,
DT::dataTableOutput('x1'),
textInput("assignGroup","Assign to group: ")),
column(6, DT::dataTableOutput('x2'))
)
)
server <- shinyServer(function(input, output, session) {
output$x1 = DT::renderDataTable(cars, server = FALSE)
output$x2 = DT::renderDataTable({
s <- input$x1_rows_selected
temp <- cars
temp$Experiment <- as.character("")
temp[s,"Experiment"] <- input$assignGroup
temp
}, server = FALSE)
})
shinyApp(ui, server)
Thanks and hope this is somewhat clear!!!
You can observe 'input$x1_rows_selected' and then edit the table on the event. To display live changes to the table, you can add a reactive table.
Hope this code works out for you.
library(shiny)
library(DT)
ui <- fluidPage(
fluidRow(
column(6,
DT::dataTableOutput('x1'),
textInput("assignGroup","Assign to group: ")
),
column(6, DT::dataTableOutput('x2'))
)
)
server <- shinyServer(function(input, output, session) {
values <- reactiveValues(
df_data = cars,
temp = {
cars[,c("Experiment")]<-NA
cars
}
)
output$x1 = DT::renderDataTable(values$df_data, server = FALSE)
observeEvent(input$x1_rows_selected,
{
s<-input$x1_rows_selected
values$temp[s,"Experiment"]<-input$assignGroup
}
)
output$x2 = DT::renderDataTable(
values$temp, server = FALSE)
})
shinyApp(ui, server)

Output more than 1 datatables in shiny main panel

I have a shiny app that a user can check whether they want the data table displayed in the main panel. Depending on the numericinput, if they select 1, only 1 datatable be displayed or if they select 2 it will display 2 datatables I am not so sure how to code this in shiny R since I am new to this. Thank you for looking into this.
Here is my code
library("shiny")
df1 <- data.frame("2010-01"=double(),
"2010-02"=double(),
"2010-03"=double(),
"2010-04"=double()
)
df1<-rbind(df1,setNames(as.list(c(10,20,30,40)), names(df2)))
df2 <- data.frame("2010-01"=double(),
"2010-02"=double(),
"2010-03"=double(),
"2010-04"=double()
)
df2<-rbind(df2,setNames(as.list(c(100,200,300,400)), names(df2)))
df3 <- data.frame("2010-01"=double(),
"2010-02"=double(),
"2010-03"=double(),
"2010-04"=double()
)
df3<-rbind(df3,setNames(as.list(c(1000,2000,3000,4000)), names(df2)))
ui <-fluidPage(
sidebarPanel(
checkboxInput("add_data", "Add Data Table(s)"),
conditionalPanel(condition="input.add_data === true",
numericInput("numofdata",
label="Number of Data Table(s):",
min = 1,
max = 3,
value = 1,
step = 1),
uiOutput("num_of_data"),
textOutput("see_ranges")
),
actionButton("submit", "Submit")
),
mainPanel(
titlePanel("Output Data Table"),
DT::dataTableOutput("datatable.view", width = "95%")
) # end of main panel
)
server <- function(input, output, session) {
output$num_of_data <- renderUI({
lapply(1:input$numofdata, function(i) {
print(trend_list())
})
})
output$see_ranges <- renderPrint({
print(trend_list())
})
data.filter <- reactive({
df(i)
})
output$datatable.view <- DT::renderDataTable(
{
input$submit
if (input$submit==0) return()
isolate({
for(i in 1:input$numoftrends) {
datatable(data.filter(i),
rownames=FALSE,
extensions = c("FixedColumns", "FixedHeader", "Scroller"),
options = list(searching=FALSE,
autoWidth=TRUE,
rownames=FALSE,
scroller=TRUE,
scrollX=TRUE,
pagelength=1,
fixedHeader=TRUE,
class='cell-border stripe',
fixedColumns =
list(leftColumns=2,heightMatch='none')
)
)
}
})
})
}
shinyApp(ui = ui, server = server)
You should look at this article:
http://shiny.rstudio.com/gallery/creating-a-ui-from-a-loop.html
You will seen then that one has to create multiple renderDataTable instead of muliple datatable within one renderDataTable().
Also in your code you call df like a function df() but it is only defined as a variable.
See a generic running example below.
EDIT: Changed dynamic part of UI.
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("amountTable", "Amount Tables", 1:10, 3)
),
mainPanel(
# UI output
uiOutput("dt")
)
)
)
server <- function(input, output, session) {
observe({
lapply(1:input$amountTable, function(amtTable) {
output[[paste0('T', amtTable)]] <- DT::renderDataTable({
iris[1:amtTable, ]
})
})
})
output$dt <- renderUI({
tagList(lapply(1:input$amountTable, function(i) {
dataTableOutput(paste0('T', i))
}))
})
}
shinyApp(ui, server)

Use selection from gvisTable in shiny

Quick question: How is it possible to use/get the selection of a gvisTable in shiny?
I can achieve this with the DT package like this:
library(DT)
library(shiny)
server <- function(input, output) {
output$dt <- renderDataTable({
datatable(cbind(c(1,2,3,4,5),c(5,4,3,2,1)))
})
output$dtselect <- renderText({
input$dt_rows_selected
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
"Selected Rows from Datatable in Text Output"
),
mainPanel(dataTableOutput("dt"),
textOutput("dtselect"))
)
)
shinyApp(ui = ui, server = server)
Is it possible to get the same selection with gvis? I googled a lot but could not find somebody reproducing the same in shiny.
You can add a listenerto the options and bind it to a variable called text as I did
rm(list = ls())
library(shiny)
library(googleVis)
mydata <- as.data.frame(cbind(c(1,2,3,4,5),c(5,4,3,2,1)))
server <- function(input, output) {
output$myTable <- renderGvis({
gvisTable(mydata, chartid = "mydata",
options = list(gvis.listener.jscode = "var text = data.getValue(chart.getSelection()[0].row,0);Shiny.onInputChange('text', text.toString());"))})
output$dtselect <- renderText({input$text})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
"Selected Rows from Datatable in Text Output"
),
mainPanel(htmlOutput("myTable"),textOutput("dtselect"))
)
)
shinyApp(ui = ui, server = server)
Variant to handle multiple selection (as told here )
library(googleVis)
library(shiny)
mydata <- as.data.frame(cbind(c(1,2,3,4,5),c(5,4,3,2,1)))
shinyApp(
ui = fluidPage(
htmlOutput("myTable")
)
,
server = function(input,output){
observe({
print(input$r_select)
})
output$myTable <- renderGvis({
gt= gvisTable(mydata,chartid="mydata")
jsInsert ="
google.visualization.events.addListener(chart, 'select', selectHandler);
var selectedRows = new Array();
function selectHandler() {
var selection = chart.getSelection();
for (var idx in selection){
var item = selection[idx];
if (item) {
i = selectedRows.indexOf(item.row);
if (i == -1){
selectedRows.push(item.row);
data.setProperty(item.row, 0,'style','background-color:#d6e9f8;');
data.setProperty(item.row, 1,'style','background-color:#d6e9f8;');
} else {
selectedRows.splice(i,1);
data.setProperty(item.row,0,'style',null);
data.setProperty(item.row,1,'style',null);
}
}
}
chart.setSelection(null);
Shiny.onInputChange('r_select',selectedRows);
chart.draw(data,options);
}
chart.draw(data,options);
"
gt$html$chart[['jsDrawChart']] <- gsub("chart.draw\\(data,options\\);", jsInsert, gt$html$chart[['jsDrawChart']])
gt
})
}
)
Print values of selected rows in observe.
Indexing start from 0

Resources