Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make runcodeUI() work inside Shiny modules #184

Closed
mjhelf opened this issue Jun 1, 2019 · 4 comments
Closed

Make runcodeUI() work inside Shiny modules #184

mjhelf opened this issue Jun 1, 2019 · 4 comments

Comments

@mjhelf
Copy link
Contributor

mjhelf commented Jun 1, 2019

Hi @daattali ,

I have been using shinyjs happily for a while and really like all the functionality it adds.

I noticed that runcodeServer()/runcodeUI combo doesn't work when called inside of Shiny modules. I could make it work by changing the runcodeUI code like this, essentially just adding an id argument that can be ignored in everyday use but can be adjusted to reflect Module namespace, and the typical shiny::NS() call.

I first thought this would be kind of a fringe use case but now I think it can be pretty useful to run code in the Module scope from the app, and this change shouldn't break anything.

Cheers,
Max

runcodeUI <- function (code = "", type = c("text", "textarea", 
                              "ace"), width = NULL, height = NULL, includeShinyjs = FALSE, id = NULL) 
{
    ns <- shiny::NS(id)
    type <- match.arg(type)
    if (type == "ace") {
        if (!requireNamespace("shinyAce", quietly = TRUE)) {
            errMsg("You need to install the 'shinyAce' package in order to use 'shinyAce' editor.")
        }
    }
    placeholder <- "Enter R code"
    shiny::singleton(shiny::tagList(if (includeShinyjs) 
        useShinyjs(), if (type == "text") 
            shiny::textInput(ns("runcode_expr"), label = NULL, 
                             value = code, width = width, placeholder = placeholder), 
        if (type == "textarea") 
            shiny::textAreaInput(ns("runcode_expr"), label = NULL, 
                                 value = code, width = width, height = height, 
                                 placeholder = placeholder), if (type == "ace") 
                                     shinyAce::aceEditor(ns("runcode_expr"), mode = "r", 
                                                         value = code, height = height, theme = "github", 
                                                         fontSize = 16), shiny::actionButton(ns("runcode_run"), 
                                                                                             "Run", class = "btn-success"), shinyjs::hidden(shiny::div(id = ns("runcode_error"), 
                                                                                                                                                       style = "color: red; font-weight: bold;", shiny::div("Oops, that resulted in an error! Try again."), 
                                                                                                                                                       shiny::div("Error: ", shiny::br(), shiny::tags$i(shiny::span(id = ns("runcode_errorMsg"), 
                                                                                                                                                                                                                    style = "margin-left: 10px;")))))))
}
@daattali
Copy link
Owner

daattali commented Jun 1, 2019

I did take deliberate steps to ensure every shinyjs functionality that I think needs to support modules will support them. Can you elaborate on why this feature needs to ever be in a module though? It's not meant to be used in multiple places in your code, it's meant as a simple tool you place in your app while developing for debugging purposes. By making it support modules I think it might make it seem more robust than it really should be.

@mjhelf
Copy link
Contributor Author

mjhelf commented Jun 1, 2019

I organize large parts of my apps in modules, and to be able to use runcode for debugging inside the module can be quite useful - I can't see reactivevalues, etc. defined inside the module scope otherwise (or maybe there is a way somehow...? IIRC inputs can be seen from everywhere provided the correctly namespaced id). Alternatively, one could construct a minimal app with the module contents, but that is a bit inconvenient, especially if the module expects some specific objects passed in from the session under a different argument name or is nested inside another module.

As an aside, using runcode multiple times in an app might be interesting too, for instance to give advanced users more flexibility in data filtering, plotting, etc, (especially by providing some template code via the code argument) without being able to easily break the app.

But I know it is intended for debugging purposes and understand your concerns about robustness - I see how this could potentially invite unintended uses and lead to problems for some users.

@daattali
Copy link
Owner

daattali commented Jun 2, 2019

Would you like to submit a PR?

@daattali
Copy link
Owner

This has been implemented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants