好,這裏是您的解決方案。我很高興找到一個,因爲它花了我幾個小時。
基本上,如果你想從無(無渲染功能)添加一個模塊,它必須通過JavaScript。這有三種措施:
- 創建HTML元素
- 與ionrangeslider.js庫
- 註冊爲滑塊創建閃亮回調
如果從閃亮調用inputSlider
,所有三個爲你完成。但沒有它,我們必須單獨做這些事情。好東西,如果你知道該怎麼做並不難。
我的代碼的重要部分發生在script
的內部。在那裏,我創建了元素(您在函數sliderUI
中嘗試過之前),然後調用ionRangeSlider
,使其看起來像一個真正的滑塊,最後,Shiny.unbindAll()/Shiny.bindAll()
爲相應的input
變量創建綁定。
其他增加只是爲了說明。
享受!
代碼:
library(shiny)
ui <- fixedPage(
fixedRow(
column(width = 4, wellPanel(
h4("Slider Module"),
tags$div(
sliderInput("slider-bins", "Number of Bins:", min = 1, max = 5, value = 3)
),
actionButton("addSliderModule", "Add Slider Module"))
),
column(width = 4, wellPanel(id = "target",
h4("Dynamic Loading Modules"),
p("Clicking on the 'Add' button on the left should add the module here. You should be able to duplicate that slider module as many times as the button is clicked"),
hr(),
tags$script('
Shiny.addCustomMessageHandler("createSlider",
function(ID) {
Shiny.unbindAll();
var targetContainer = document.getElementById("target");
var container = document.createElement("div");
container.setAttribute("class", "form-group shiny-input-container");
var label = document.createElement("label");
label.setAttribute("class", "control-label");
label.setAttribute("for", "ID");
var labelText = document.createTextNode("Number of Bins");
label.appendChild(labelText);
container.appendChild(label);
var input = document.createElement("input");
input.setAttribute("class", "js-range-slider");
input.setAttribute("id", ID);
input.setAttribute("data-min", "1");
input.setAttribute("data-max", "5");
input.setAttribute("data-from", "3");
input.setAttribute("data-step", "1");
input.setAttribute("data-grid", "true");
input.setAttribute("data-grid-num", "4");
input.setAttribute("data-grid-snap", "false");
input.setAttribute("data-prettify-separator", ",");
input.setAttribute("data-keyboard", "true");
input.setAttribute("data-keyboard-step", "25");
input.setAttribute("data-drag-interval", "true");
input.setAttribute("data-data-type", "number");
container.appendChild(input);
targetContainer.appendChild(container);
$("#" + ID).ionRangeSlider();
Shiny.bindAll();
}
);'
)
)),
column(width = 4, wellPanel(
uiOutput("response")
))
)
)
server <- function(input, output, session) {
observeEvent(input$addSliderModule, {
session$sendCustomMessage(type = "createSlider", message = paste0("slider-", input$addSliderModule))
})
output$response <- renderUI({
if(input$addSliderModule >0){
lapply(1:input$addSliderModule, function(x){
output[[paste("response", x)]] <- renderText({paste("Value of slider", x, ":", input[[paste0("slider-", x)]])})
textOutput(paste("response", x))
})
}
})
}
runApp(shinyApp(ui, server))
我無法掌握你實際想要做的事情。你首先想要在一個井中渲染一個Slider,並在Button Click上將其位置更改爲另一個?你有沒有在服務器中的任何代碼來響應你的按鈕?爲什麼renderUI不是你正在尋找的? –
隨着我瞭解它的renderUI,你把一個佔位符內的UI功能,然後你寫你的控制/小部件內的服務器功能。模塊分兩部分。一部分你必須添加到UI功能和另一部分添加到服務器功能使用calllModule。如果有幫助,您可以考慮在點擊按鈕時多次重複模塊。重複的模塊應該都是獨立的。 – MySchizoBuddy
我改進了問題並更好地解釋了我想要的視覺 – MySchizoBuddy