What is the reason behind JavaScript being able to alter pre-designed shiny UI components but not ones that are inserted through insert

Is it possible to use JavaScript to control attributes of a class of UI elements, including those added dynamically using insertUI? In this scenario, a colored box is inserted each time a button is pressed. The color is meant to change based on user input but only affects the initial div and not subsequent additions.

The issue arises from the script defined within the UI not targeting the additional divs. How can we modify the script to apply changes to all divs with the matching Id prefix?

library(shiny)
library(magrittr)

# Function to insert a colored box
insertBox = function(Id) {
  boxDiv = tags$div(id = paste0("color_", Id),
                   style = "height:30px; width: 30px; background-color: blue;"
  )

  return(boxDiv)
}

# Script to update attribute values for matching Id prefixes
jsChangeDivAttr = function(event, Id, attribute) {
  script = tags$script(HTML(paste0("$(document).on('shiny:inputchanged', function(event) {
    if(event.name == '", event, "') {
        var divs = document.querySelectorAll('[id^=\"", Id, "\"]');
        for (var i = 0; i < divs.length; i++) {
          divs[i].style.setProperty('", attribute, "', event.value);
        }
    }
  });")))
  
  return(script)
}

# UI
ui = fluidPage(
  # Script for changing div properties
  tags$head(
    jsChangeDivAttr(event = "boxColor", Id = "color", attribute = "background-color")
  ),

  # Select color for div
  selectizeInput("boxColor", choices = c("blue", "red"), label = "Box color"),

  # Button to add new div
  actionButton("insertBoxButton", label = "Insert box"),

  # Insert text and color divs
  insertBox(0)
)

# Server
server = function(input, output, session) {
  idCount = reactiveVal(0)

  observe({
    Id = idCount()

    idCount(idCount() + 1)

    insertUI(selector = paste0("#color_", Id), where = "afterEnd", ui = insertBox(idCount()))
  }) %>% 
    bindEvent(input$insertBoxButton)
}

shinyApp(ui, server)

Edit 2023-08-30

Updated based on feedback to address issues with updating multiple divs:

script = tags$script(HTML(paste0("$(document).on('shiny:inputchanged', function(event) {
  if(event.name == '", event, "') {
    var divs = document.querySelectorAll('[id^=\"", Id, "\"]');
    for (var i = 0; i < divs.length; i++) {
      divs[i].style.setProperty('", attribute, "', event.value);
    }
  }
});")))

Answer №1

When you utilize the querySelector function, it retrieves the first element that corresponds to a CSS selector. To retrieve all matches (not just the first one), opt for using the querySelectorAll() method.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to enable autofill functionality if an email already exists in the database or API within Angular 12?

In order to auto-fill all required input fields if the email already exists in the database, I am looking for a way to implement this feature using API in Angular. Any guidance or suggestions on how to achieve this would be greatly appreciated. ...

Excessive padding on labels and insufficient padding on input fields in Bootstrap 4 mobile view

Having a simple password field using Bootstrap grid classes: <div class="container"> <div class="row"> <label class="col-sm-2" for="passwordField">Password</label> <input class=&q ...

How to delete the final character from a file stream using node.js and the fs module

My current project involves using node.js to create an array of objects and save them to a file, utilizing the fs library. Initially, I set up the write stream with var file = fs.createWriteStream('arrayOfObjects.json'); and wrote an opening brac ...

The functionality of ngClass fails to toggle the value appropriately when utilizing an object within a component

When implementing the code below to toggle the class, everything runs smoothly <p [ngClass]="idPresent ? 'alert alert-success' : 'alert alert-danger'"> Working </p> After changing the value of IdPresent in the c ...

When the text input is selected, automatically scroll to the bottom

I found a codepen example by Chris Coyer and decided to fork it. My goal is to make the label move to the top instead of staying at the bottom, as in his original design. However, I am facing an issue with getting the cursor to move to the bottom when typ ...

Twitter Bootstrap 3.3.5 navigation menu with a drop-down feature aligned to the right

I've been attempting to position the drop-down menu all the way to the right, following the search input field and submit button. I've tried using pull-right and navbar-right classes without success. Is there a method to accomplish this? <na ...

Experiencing blank areas when I try to minimize the screen while using Chrome

While using Chrome, my webpage looks perfect in normal mode. However, when I minimize the screen, white space appears at the bottom and some content gets hidden. The page is built using reactjs, html, and css. Interestingly, it works fine for IE in both no ...

Implement SCSS in Next.js 12 using Bootstrap

Ever since updating Next.js to version 12, I've been encountering issues with Bootstrap and SCSS integration. In my project, I have a global.scss file that is imported in the _app.js. Within this file, I include imports for Bootstrap and Bootstrap Ic ...

What is the necessity of explicitly requesting certain core modules in Node.js?

The documentation explains that certain core modules are included in the Node.js platform itself and are specified within the source code. The terminology can get a bit confusing when it comes to details. The term "global objects" (or standard built-in obj ...

Mastering Vuex: effectively managing intricate data structures and dynamic state transformations

Let's say I'm utilizing an external API that interacts with Machine objects. With the API, you can create a Machine using createMachine, resulting in a complex object with various nested properties and functions to modify its state. The API inclu ...

Instructions on creating an individual DropdownIndicator component with React-select for the purpose of reusability in different sections of the project

The code below functions properly when the DropdownIndicator component is kept in the same file. However, I am interested in separating DropdownIndicator into its own file so that it can be reused. This way, it can be used as a separate component and incl ...

Creating camera shake in Three.js: A beginner's guide

I've been searching for hours online and I can't seem to figure this out. Is there any way to achieve this? If so, please share the steps with me. I found a code snippet but I'm unsure how to implement it properly. Can someone guide me on ho ...

Is there a way to retrieve the transaction specifics for the initial 50 clients from a MongoDB database?

In my PC's local server, there is a cluster with approximately 240,000 entries of transaction data. The abbreviation Cust_ID represents Customer ID. https://i.sstatic.net/5g65l.png Each file contains transactions made by different customers, with a ...

Stripping particular labels off a string in R

I checked out some similar questions and tried to apply the solutions to my situation, but unfortunately they didn't work. So, I'm wondering - how can I successfully remove the <\/p>\r\n<p> sequence from a string? Here ...

HTML - Ways to showcase multiple forms on a single row?

I have three forms in my Flask application that I want to display in a single line rather than one after the other. Is there a way to achieve this without using CSS? Here is the HTML snippet: <form action="/pull_entity_by_manufacturer" metho ...

Utilize jQuery to dynamically swap out a CSS stylesheet in response to changes in the body class

In the head section of my HTML, I have the following stylesheet: <link rel="stylesheet" href="/templates/jooswatch-v3-5/css/bootswatch/superhero/bootstrap.min.css"> I want to replace this stylesheet with different ones based on changes in the body# ...

A guide on how to display slotted ng-template within Angular applications

I've created a customized component called tab. The structure of the template for the tab component is as follows: <ng-content></ng-content> When utilizing the tab component, it is done like this: <tab> <ng-template> . ...

Vue.js Issue: Image not properly redirected to backend server

Having an issue with my Vue app connecting to the backend using express. When I attempt to include an image in the request, it doesn't reach the backend properly. Strangely though, if I bypass express and connect directly from the Vue app, everything ...

Changing the Class of an Element in a Different Component with Angular 2+

Currently in a project utilizing Angular 4, I have implemented two components: app.component and other.component Within app.component.html, there exists a div with the name attribute myClass. <div class="myClass"></div> In the other.componen ...

operations involving loop and condition statements

Hello! I am facing an issue and I am hoping that someone can assist me. I have a dataframe in R with a nested loop and conditional statement. The dataframe contains values and based on a specific condition being met, certain operations are performed. Howev ...