Either/Or text entry in Shiny?

Here's my very basic Shiny app that takes in whatever text the user supplies and displays it.
There are two text boxes, and two outputs.

How can I make this work such that if text is entered in Box 1, nothing can be entered in Box 2 ?
(or vice-versa, if user types in Box2, box1 is 'ghosted' or does not allow typing) ?

## Only run this example in interactive R sessions
if (interactive()) {
  shinyApp(
    ui = basicPage(
      
      
      textInput("text1", "Enter the text to display below:"),
      paste0("output of textbox #1"),
      textOutput("text1"),
      
      
      
      textInput("text2", "Enter the text to display below:"),
      paste0("output of textbox #2"),
      textOutput("text2")
    ),
    server = function(input, output) {
      output$text1 <- renderText({ input$text1 })
      output$text2 <- renderText({ input$text2 })
    }
  )
}

The shinyjs package includes functions to disable controls.

library(shiny)
library(shinyjs)

shinyApp(
  ui = basicPage(
    useShinyjs(),
    textInput("text1", "Enter the text to display below:"),
    paste0("output of textbox #1"),
    textOutput("text1"),
    textInput("text2", "Enter the text to display below:"),
    paste0("output of textbox #2"),
    textOutput("text2")
  ),
  server = function(input, output) {
    output$text1 <- renderText({
      req(input$text1)
      shinyjs::disable("text2")
      input$text1
    })
    output$text2 <- renderText({
      req(input$text2)
      shinyjs::disable("text1")
      input$text2
    })
  }
)

I have been studying your example and trying to merge it with another one I found, but so far no success.

I am definitely going to be using shinyjs like you mentioned.

If I have a dropdown and select option1, I only want tab1 to be available. If I select option2, I only want tab2 to be available. The first seems to work, but I can't modify it for the second one. Any ideas?

library(shiny)
library(shinyjs)

jscode <- '
  shinyjs.init = function() {
  $(".nav").on("click", ".disabled", function (e) {
  e.preventDefault();
  return false;
  });
  }'

css <- '
  .disabled {
  background: #eee !important;
  cursor: default !important;
  color: black !important;
  }'

shinyApp(
  ui = fluidPage(
    useShinyjs(),
    extendShinyjs(text = jscode, functions = "init"),
    tags$style(css),
    
    
    selectizeInput("foo", "Select an option",  selected = NULL ,choices=c("Option1","Option2"), multiple = TRUE),
    
    
    tabsetPanel(
      
      
      id = "navbar",
      tabPanel(title = "Option1",
               value = "tab1",
               h1("This is Option1")
      ),
      tabPanel(title = "Option2",
               value = "tab2",
               h1("This is Option2")
      )
    )
    
    
  ),
  server = function(input, output) {
    observe(print(length(input$foo)==1))
    observe({
      toggleClass(selector = "#navbar li a[data-value=tab2]", class = "disabled",
                  condition = length(input$foo)==1)
      
    })})

I can't help you with javascript, but shinyjs also has a hide() function. It might work on the tabs.

I rarely use observe(), as it constantly monitors its dependencies. I think it's better to use observeEvent() since it is only triggered things you control.