1 Shiny Form Validation with Relational Data and Machine Learning

1.1 Can Shiny Create Forms with Real-Time Validation?

Yes, Shiny can create forms with real-time validation by using built-in reactive validation functions and JavaScript-based checks. Shiny provides several approaches for validating user input before submission.


1.2 Methods for Real-Time Validation in Shiny

1.2.1 1. validate() and need() for Simple Input Validation

  • These functions allow dynamic validation of form inputs.
  • Error messages are displayed instantly when an invalid input is detected.

1.2.1.1 Example: Age Validation (Must be Between 18-65)

library(shiny)

ui <- fluidPage(
    titlePanel("Real-Time Validation Example"),
    sidebarLayout(
        sidebarPanel(
            numericInput("age", "Enter Age:", value = NULL, min = 0, max = 100),
            verbatimTextOutput("validation_message"),
            actionButton("submit", "Submit")
        ),
        mainPanel()
    )
)

server <- function(input, output, session) {
    output$validation_message <- renderText({
        validate(
            need(input$age >= 18, "Age must be at least 18"),
            need(input$age <= 65, "Age must be 65 or below")
        )
        "Valid input!"
    })
}

shinyApp(ui, server)

1.2.2 2. shinyvalidate Package for Advanced Form Validation

The shinyvalidate package allows multiple dependent form inputs to be validated before submission.

1.2.2.1 Example: Multiple Field Validation (Email & Age)

library(shiny)
library(shinyvalidate)

ui <- fluidPage(
    titlePanel("Shinyvalidate Example"),
    textInput("email", "Enter Email:"),
    numericInput("age", "Enter Age:", value = NULL, min = 0, max = 100),
    actionButton("submit", "Submit"),
    verbatimTextOutput("validation_message")
)

server <- function(input, output, session) {
    iv <- InputValidator$new()
    
    iv$add_rule("email", sv_email()) # Validates email format
    iv$add_rule("age", sv_between(18, 65)) # Age must be between 18 and 65
    
    iv$enable()
    
    observeEvent(input$submit, {
        if (iv$is_valid()) {
            showModal(modalDialog("Form submitted successfully!"))
        } else {
            showModal(modalDialog("Please fix errors before submitting."))
        }
    })
}

shinyApp(ui, server)

1.2.3 3. JavaScript-Based Validation for Immediate Feedback

Shiny supports JavaScript validation for client-side real-time validation before sending data to the server.

1.2.3.1 Example: Real-Time Numeric Input Restriction

library(shiny)

ui <- fluidPage(
    tags$script(HTML("
        function validateNumericInput() {
            var input = document.getElementById('numInput').value;
            if (isNaN(input) || input < 1 || input > 100) {
                document.getElementById('error').innerHTML = 'Enter a valid number (1-100)';
            } else {
                document.getElementById('error').innerHTML = '';
            }
        }
    ")),
    textInput("numInput", "Enter a number:", "", oninput = "validateNumericInput()"),
    span(id = "error", style = "color: red;")
)

server <- function(input, output, session) {}

shinyApp(ui, server)

1.3 Can JavaScript Access Relational Data and Machine Learning Tools?

Yes, JavaScript can access relational datasets and machine learning tools for real-time validation. This can be achieved through:

  1. Client-Side Validation via IndexedDB (local relational database in browser)
  2. AJAX Requests to Query a Remote Database (MySQL, PostgreSQL, etc.)
  3. Calling a Machine Learning Model via an API (TensorFlow.js, Python API)
  4. WebAssembly (WASM) for Local ML Computation

1.4 1. Using IndexedDB for Local Relational Data Validation

<script>
  let db;
  
  // Open IndexedDB database
  let request = indexedDB.open("ClinicalDB", 1);
  request.onsuccess = function(event) {
      db = event.target.result;
  };
  
  function validateUserID() {
      let inputID = document.getElementById("userID").value;
      let transaction = db.transaction(["patients"]);
      let objectStore = transaction.objectStore("patients");
      let request = objectStore.get(inputID);
      
      request.onsuccess = function() {
          if (!request.result) {
              document.getElementById("error").innerHTML = "Invalid Patient ID!";
          } else {
              document.getElementById("error").innerHTML = "";
          }
      };
  }
</script>
<input id="userID" type="text" oninput="validateUserID()">
<span id="error" style="color: red;"></span>

1.5 2. Using AJAX to Query a Remote SQL Database

<script>
  function checkPatientID() {
      let userID = document.getElementById("userID").value;
      fetch(`/validate_id?userID=${userID}`)
          .then(response => response.json())
          .then(data => {
              if (data.valid) {
                  document.getElementById("error").innerHTML = "";
              } else {
                  document.getElementById("error").innerHTML = "Invalid Patient ID!";
              }
          });
  }
</script>
<input id="userID" type="text" oninput="checkPatientID()">
<span id="error" style="color: red;"></span>

1.6 3. Calling a Machine Learning Model for Validation

<script>
  function validateAdverseEvent() {
      let eventText = document.getElementById("eventText").value;
      fetch(`/predict_adverse_event`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ "text": eventText })
      })
      .then(response => response.json())
      .then(data => {
          document.getElementById("error").innerHTML = 
              data.valid ? "" : "Potentially invalid event!";
      });
  }
</script>
<input id="eventText" type="text" oninput="validateAdverseEvent()">
<span id="error" style="color: red;"></span>

1.7 Choosing the Best Approach

Approach Best For Needs Server?
IndexedDB Local relational checks ❌ No
AJAX (SQL Backend) Large relational datasets ✅ Yes
ML API (Python/Flask) Advanced validation via AI ✅ Yes
TensorFlow.js Local ML without server ❌ No

1.8 Conclusion

  • For small datasets, use IndexedDB (local relational validation).
  • For real-time database validation, use AJAX + SQL backend.
  • For AI-powered checks, use Flask ML API or TensorFlow.js.

Reuse

Citation

BibTeX citation:
@online{(ryy)_glenn_thomas,
  author = {(Ryy) Glenn Thomas, Ronald},
  url = {https://focusonr.org/posts/rct_validation_lang/Shiny_Validation.html},
  langid = {en}
}
For attribution, please cite this work as:
(Ryy) Glenn Thomas, Ronald. n.d. https://focusonr.org/posts/rct_validation_lang/Shiny_Validation.html.