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

shinyjs::reset is not resetting passwordInput() inside module #78

Closed
ghost opened this issue Aug 19, 2016 · 3 comments
Closed

shinyjs::reset is not resetting passwordInput() inside module #78

ghost opened this issue Aug 19, 2016 · 3 comments

Comments

@ghost
Copy link

ghost commented Aug 19, 2016

After scouring the internet to see if anyone else has ran into this problem, I finally decided to turn to this. Here is the problem: I have a shiny form. Said shiny form is built to gather data from a user and send the results to a MySQL database to create users. The form takes textInput() for a username, passwordInput() for a password, and then selectInput() for assigning permissions to the user (Admin or Guest). After the user submits the form, the UI shows a thank you message, resets the form using shinyjs::reset, hides the form, and a link back to the form will display a blank form again. Except the password field which contains the data that was previously entered. I have tried inserting raw HTML to mimic the textInput() field, which I will include below, but that also did not work. I'm relatively new to shiny, so sorry if it looks clunky.

Here is some version info:

> version
               _                           
platform       x86_64-pc-linux-gnu         
arch           x86_64                      
os             linux-gnu                   
system         x86_64, linux-gnu           
status                                     
major          3                           
minor          3.1                         
year           2016                        
month          06                          
day            21                          
svn rev        70800                       
language       R                           
version.string R version 3.3.1 (2016-06-21)
nickname       Bug in Your Hair           

> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.4 LTS

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8   
 [6] LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] pool_0.1.0    RMySQL_0.10.9 DBI_0.5       shinyjs_0.6   shiny_0.13.2 

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.5     digest_0.6.9    withr_1.0.2     mime_0.5        R6_2.1.2        xtable_1.8-2    jsonlite_1.0    git2r_0.15.0    httr_1.2.1     
[10] curl_1.2        miniUI_0.1.1    devtools_1.12.0 tools_3.3.1     httpuv_1.3.3    memoise_1.0.0   htmltools_0.3.5 knitr_1.13     

Here is the html code I manually inserted with Chrome developer tools:

<input id="addUserSQLtest-passwdAdd" type="password" class="form-control shiny-bound-input" value="" data-shinyjs-resettable-id="addUserSQLtest-passwdAdd" data-shinyjs-resettable-type="password" data-shinyjs-resettable-value="">

Here is the html code that does reset for the textInput() field:

<input id="addUserSQLtest-userNameAdd" type="text" class="form-control shiny-bound-input shinyjs-resettable" value="" data-shinyjs-resettable-id="addUserSQLtest-userNameAdd" data-shinyjs-resettable-type="Text" data-shinyjs-resettable-value="">

The App.R and UserDB.R files are below. Thanks!

App.R

##App.R
library(shiny)
library(shinyjs)

source("UserDB.R")



TestUI <- function(id){

    # Define UI for application that draws a histogram
    navbarPage("Test UI", inverse = TRUE,
                tabPanel("Admin",
                      uiOutput("adminTab")       
                 )


                    )
}

# Define server logic required to draw a histogram
Test <- function(input, output, session) {

      callModule(addUserSQL, "addUserSQLtest")

      output$adminTab <- renderUI({
        shinyjs::useShinyjs()
        addUserSQLInput("addUserSQLtest")
      })
}

shinyApp(ui = TestUI, server = Test)

UserDB.R

library(RMySQL)
library(DBI)
library(shiny)
library(shinyjs)

############Previous Attempts to fix resetting passwordInput()##################

#passwdInput <- function(inputId, label) {
#  div(class = "form-group shiny-input-container",
#  tagList(
#    tags$label(label),
#    tags$input(id = inputId, type="password", class = "form-control shiny-bound-input shinyjs-resettable", value="", data-shinyjs-resettable-id, data-shinyjs-resettable-type, data-shinyjs-resettable-value)
#  ))
#}

#passwdInputSQL(
#  div( class = "form-group shiny-input-container",
#    HTML("")
#  )
#)

####################################################

##########Global Functions##########################

# add an asterisk to an input label
labelMandatorySQL <- function(label) {
  tagList(
    label,
    span("*", class = "mandatory_star")
  )
}

# CSS to use in the app
appCSS <-
  ".mandatory_star { color: red; }
  .shiny-input-container { margin-top: 25px; }
  #submit_msg { margin-left: 15px; }
  #error { color: red; }
  #adminPanel { border: 4px solid #aaa; padding: 0 20px 20px; }"

# which fields get saved 
fieldsAllSQL <- c("userNameAdd", "passwdAdd", "privsAdd")

# which fields are mandatory
fieldsMandatorySQL <- c("userNameAdd", "passwdAdd", "privsAdd")

#####DEPS####
# Install most current dev version of pool and shiny 
# devtools::install_github("rstudio/shinyjs")
# devtools::install_github("rstudio/shiny")


#############Add/Modify/Delete User UI#############################
######################################################################################
addUserSQLInput <- function(id) {
  ns <- NS(id)

  fluidPage(
    shinyjs::useShinyjs(),
    shinyjs::inlineCSS(appCSS),
    fluidRow(
      column(6, offset=1,
      div(id = ns('adminAdd'),
      textInput(ns("userNameAdd"), labelMandatorySQL("Username:")),
#      passwdInput(ns("passwdAdd"), labelMandatorySQL("Password:")),

      passwordInput(ns('passwdAdd'), labelMandatorySQL("Password:"), value=""),
      selectInput(ns("privsAdd"), labelMandatorySQL("Privileges:"), c(" ", "Admin" = "Admin", "Guest" = "Guest")),
      br(),

      actionButton(ns("AddUser"), "Create", class = "btn-primary"),

      shinyjs::hidden(
        span(id = ns("submit_msg_sql"), "Submitting..."),
        div(id = ns("error_sql"),
            div(br(), tags$b("Error: "), span(id = "error_msg_sql"))
        )
      )
    ),
    shinyjs::hidden(
      div(
        id = ns("thankyou_msg_sql"),
        h3("Thanks, your response was submitted successfully!"),
        actionLink(ns("submit_another_sql"), "Submit another response")
      )
    )
    )))

}

addUserSQL <- function(input, output, session){

  observe({
    mandatoryFilledSQL <-
      vapply(fieldsMandatorySQL,
             function(x) {
               !is.null(input[[x]]) && input[[x]] != "" && input[[x]] != " "
             },
             logical(1))
    mandatoryFilledSQL <- all(mandatoryFilledSQL)

    shinyjs::toggleState(id = "AddUser", condition = mandatoryFilledSQL)
    shinyjs::toggleState("AddUser", (mandatoryFilledSQL))

  })


  # Gather all the form inputs (and add timestamp)
  formDataSQL <- reactive({
    dataSQL <- sapply(fieldsAllSQL, function(x) input[[x]])
    dataSQL
  })

  observeEvent(input$AddUser, {

    # User-experience stuff
    shinyjs::disable("AddUser")
    shinyjs::show("submit_msg_sql")
    shinyjs::hide("error_sql")  

    tryCatch({
      ####################################
      usrnmadd <- isolate(input$userNameAdd)
      pswdadd <- isolate(input$passwdAdd)

      passCryptAdd <- system(paste0("echo -n '", pswdadd,"' | md5sum | awk '{print $1}'"), intern = TRUE, wait = TRUE)

      conn <- dbConnect(
        drv = RMySQL::MySQL(),
        dbname = "dbname",
        host = "127.0.0.1",
        username = "guest",
        password = "guest")
      on.exit(dbDisconnect(conn), add = TRUE)
      sql <- "INSERT INTO dbname.members (usr,pass,priv) VALUES (?id1, ?id2, ?id3);"
      query <- sqlInterpolate(conn, sql, id1 = input$userNameAdd, id2 = passCryptAdd, id3 = input$privsAdd)
      dbGetQuery(conn, query)
      #####################################

      shinyjs::reset("adminAdd")
#      updateTextInput(session, "passwdAdd", value = NULL)
      shinyjs::hide("adminAdd")
      shinyjs::show("thankyou_msg_sql")  
      },

      error = function(err) {
        shinyjs::html("error_msg_sql", err$message)
        shinyjs::show("error_sql", anim = TRUE, animType = "fade")
      },

      finally = {
        shinyjs::enable("adminAdd")
        shinyjs::hide("submit_msg_sql")
      }
    )

    # submit another response
    observeEvent(input$submit_another_sql, {
      shinyjs::show("adminAdd")
      shinyjs::hide("thankyou_msg_sql")
    })

  })
}
@daattali
Copy link
Owner

Thank you for the very detailed report. Could you please send an example that is more minimal? Debugging the problem within such an involved app is going to be hard, it really helps if you isolate the problem. It'd also help to know if this is only happening inside modules or if it's a problem in general

@ghost
Copy link
Author

ghost commented Aug 20, 2016

Sorry about that, here is a basic example that is non-modular (I ran it and it still does not work even as a non-modular app).

App.R

##TestUI.R
library(shiny)
library(shinyjs)

TestUI <- function(id){

  # Define UI for application that draws a histogram
  navbarPage("Test UI", inverse = TRUE,
             tabPanel("Admin",
                      uiOutput("adminTab")       
             )


  )
}

# Define server logic required to draw a histogram
Test <- function(input, output, session) {

  output$adminTab <- renderUI({
    fluidPage(
      shinyjs::useShinyjs(),
      fluidRow(
        column(6, offset=1,
               div(id = 'adminAdd',
                   textInput("userNameAdd", "Username:"),
                   passwordInput('passwdAdd', "Password:", value=""),
                   selectInput("privsAdd", "Privileges:", c(" ", "Admin" = "Admin", "Guest" = "Guest")),
                   br(),

                   actionButton("AddUser", "Create", class = "btn-primary")

))))
  })


  observeEvent(input$AddUser, {

    tryCatch({
      shinyjs::reset("adminAdd")
    })

  })
}

shinyApp(ui = TestUI, server = Test)

@daattali
Copy link
Owner

Thank you. That really makes it a lot easier to debug the problem :)


http://deanattali.com

On 20 August 2016 at 08:17, shinyuser [email protected] wrote:

Sorry about that, here is a basic example that is non-modular (I ran it
and it still does not work even as a non-modular app).
App.R

##TestUI.R
library(shiny)
library(shinyjs)
TestUI <- function(id){

Define UI for application that draws a histogram

navbarPage("Test UI", inverse = TRUE,
tabPanel("Admin",
uiOutput("adminTab")
)

)
}

Define server logic required to draw a histogramTest <- function(input, output, session) {

output$adminTab <- renderUI({
fluidPage(
shinyjs::useShinyjs(),
fluidRow(
column(6, offset=1,
div(id = 'adminAdd',
textInput("userNameAdd", "Username:"),
passwordInput('passwdAdd', "Password:", value=""),
selectInput("privsAdd", "Privileges:", c(" ", "Admin" = "Admin", "Guest" = "Guest")),
br(),

               actionButton("AddUser", "Create", class = "btn-primary")

))))
})

observeEvent(input$AddUser, {

tryCatch({
  shinyjs::reset("adminAdd")
})

})
}

shinyApp(ui = TestUI, server = Test)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#78 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AA6IFC5rKv0gce8rvMloY_ViFy8X84PYks5qhxqVgaJpZM4Jo7Ih
.

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

1 participant