2015-11-14 288 views
0

我已經搜查相當長一段時間了,但我還沒有找到一個解決我的問題不同類型的表格輸入。我建立一個項目管理應用程序,我想使用有光澤,因爲我認爲這將能夠使應用程序更具交互性。[R閃亮:動態創建

因此應用程序的輸入應該在應用程序內完成。輸入將是數字,文本和選擇。對於概述,屬於一起的輸入應排列在一行中。例如:

resource_1,NAME = '共聚焦顯微鏡',鍵入= '機',價格= 1000,價格類型= 'EUR /使用'

我想安排在一個表格中的每個條目。當然,條目的數量是可變的。有時你可能會爲某個項目定義5個資源,有時候是50個。

爲了解決這個問題,我創建了一個閃亮的html表格作爲表格條目。但是,我需要動態訪問這些條目。我想我能做到這一點通過調用的get()函數中的每個表項的輸入ID的字符串。但那不行。

目前:

  • 我可以創建具有不同類型的輸入和行的可變數量的表格。

  • 我可以通過實際調用輸入ID(如「輸入$ element1_1」

  • 相互調用這些輸入,但我不能讓一個循環來自動獲取這些輸入標識的,像get()方法:得到(paste0( '輸入$元素',我, '_',J))

小例子:

library(shiny) 

ui = 
    pageWithSidebar(

headerPanel("TEST"), 

sidebarPanel(
    helpText("number of resources"), 
    numericInput("nres","",3,min=0), 
    actionButton('create_res',"create",icon=icon("plus"),width='100%'), 
    br(), 
    br(), 
    br(), 
    bsButton('finish_res',"finish",width='100%',style="info"), # check matrix 
    width=2 
), 

mainPanel( 
    uiOutput('matrix_res'), 
    p("make an entry in row1 col1 and press finish"), 
    br(), 
    p("I can extract elements by calling input$element1_1:"), 
    textOutput('check1'), 
    br(), 
    p("but not by searching for the character string with get('element1_1') "), 
    textOutput('check2') 
) 
) 

server = 
    function(input,output){ 

output$matrix_res <- renderTable({ 

    input$create_res #create button dependency 


    Row_entries <- paste("ressource",1:isolate(input$nres)) #kill nres dependency 
    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    for (i in 1:length(Row_entries)) { 
    matrix[i,1] <- paste0("<input id='element", i, "_", 1, "' class='shiny-bound-input span6' type='text' value=''>") 
    matrix[i,2] <- paste0("<input id='element", i, "_", 2, "' class='shiny-bound-input span6' type='number' value=''>") 
    matrix[i,3] <- paste0("<div class='form-group shiny-input-container'> 
          <div> 
          <select id='element", i, "_", 3, "' class='form-control'><option value='a' selected>a</option> 
          <option value='b'>b</option></select> 
          <script type='application/json' data-for='element", i, "_", 3, "'>{}</script> 
          </div></div>") 
    } 

    colnames(matrix) <- Col_entries 

    matrix 

    },sanitize.text.function = identity) 


output$check1<-renderText({ 
    input$finish_res 
    isolate(input$element1_1) 
}) 

output$check2<-renderText({ 
    input$finish_res 
    isolate(input$get('element1_1')) 
}) 
} 

runApp(list(ui = ui, server = server)) 

運行:您可以通過更改的行數號碼輸入和創建按鈕。您可以通過點擊完成調用ROW1列1的值。

如果您有任何想法如何獲得這些輸入,請回復。我卡在這個狗屎已經一個星期...

回答

0

所以我找到了一個令人不滿意的答案。 我使用get(),eval()函數,do.call()和下面的實際工作試圖圍繞:

的eval(解析(文= character_string))

這樣就可以使character_string < - paste0( 'input $ element',i,'_',j)或者其他東西

所以,通過這個,你可以創建一個循環遍歷所有的輸入併爲所有輸入創建一個列表。其實,我希望它可以將所有的輸入直接保存到列表中。

所以這裏有一個例子:

library(shiny) 

ui = 
pageWithSidebar(

headerPanel("TEST"), 

sidebarPanel(
    helpText("number of rows"), 
    numericInput("nres","",3,min=0), 
    actionButton('create_res',"create",icon=icon("plus"),width='100%'), 
    br(), 
    br(), 
    br(), 
    helpText("show me value in row 1 column 1"), 
    actionButton('finish_res',"show",icon=icon("check"),width='100%'), 
    width=2 
), 

mainPanel( 
    uiOutput('matrix_res'), 
    p("just by actually writing 'input$element1_1'"), 
    textOutput('check1'), 
    br(), 
    p("with get(character_string)"), 
    textOutput('check2'), 
    br(), 
    p('with eval(parse(text=character_string)):'), 
    textOutput('check3'), 
    br(), 
    p('with do.call("print", list(as.name(character_string)))'), 
    textOutput('check4') 
) 
) 

server = 
function(input,output){ 

output$matrix_res <- renderTable({ 

    input$create_res #create button dependency 


    Row_entries <- paste("ressource",1:isolate(input$nres)) #kill nres dependency 
    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    for (i in 1:length(Row_entries)) { 
    matrix[i,1] <- paste0("<input id='element", i, "_", 1, "' class='shiny-bound-input span6' type='text' value=''>") 
    matrix[i,2] <- paste0("<input id='element", i, "_", 2, "' class='shiny-bound-input span6' type='number' value=''>") 
    matrix[i,3] <- paste0("<div class='form-group shiny-input-container'> 
          <div> 
          <select id='element", i, "_", 3, "' class='form-control'><option value='a' selected>a</option> 
          <option value='b'>b</option></select> 
          <script type='application/json' data-for='element", i, "_", 3, "'>{}</script> 
          </div></div>") 
    } 

    colnames(matrix) <- Col_entries 

    matrix 

    },sanitize.text.function = identity) 


output$check1<-renderText({ 
    input$finish_res 
    isolate(input$element1_1) 
}) 

output$check2<-renderText({ 
    input$finish_res 
    isolate(get(paste0('input$element',1,'_',1))) 
}) 

output$check3<-renderText({ 
    input$finish_res 
    isolate(eval(parse(text=paste0('input$element',1,'_',1)))) 
}) 

output$check4<-renderText({ 
    input$finish_res 
    isolate(do.call("print", list(as.name(paste0('input$element',1,'_',1))))) 
}) 

} 

runApp(list(ui = ui, server = server)) 
0

確定這裏是得到我想要的東西的一種方式。

我確信有這樣做的更好的方法,因爲這對於一個簡單的任務來說太複雜了。

請注意,如果您決定添加更多行,則會保存輸入。

library(shiny) 

ui <- 
pageWithSidebar(

headerPanel("Dynamic table for Input of different types"), 

sidebarPanel(
    helpText("number of rows"), 
    numericInput("nres","",3,min=0), 
    actionButton('create_res',"create",icon=icon("plus"),width='100%'), 
    br(), 
    br(), 
    br(), 
    helpText("read input you entered"), 
    actionButton('finish_res',"finish",icon=icon("check"),width='100%'), 
    width=2 
), 

mainPanel( 
    h3("input table"), 
    uiOutput('matrix_res'), 
    h3("output table"), 
    tableOutput('check_table'), 
    br() 

) 
) 

server <- 
function(input,output){ 


# input table 
# table with different types of input 
# row number can be changed with number input 
# changes are applied after pressing create button 
output$matrix_res <- renderTable({ 

    input$create_res # dependency 


    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    for (i in 1:isolate(input$nres)) { 
    matrix[i,1] <- paste0("<input id='element", i, "_", 1, "' class='shiny-bound-input span6' type='text' value='",input[[paste0("element", i, "_", 1)]],"'>") 
    matrix[i,2] <- paste0("<input id='element", i, "_", 2, "' class='shiny-bound-input span6' type='number' value='",input[[paste0("element", i, "_", 2)]],"'>") 
    matrix[i,3] <- paste0("<div class='form-group shiny-input-container'><div> 
          <select id='element", i, "_", 3, "' class='form-control'> 
          <option value='a'>a</option> 
          <option value='b'>b</option> 
          </div></div>") 
    } 

    colnames(matrix) <- Col_entries 

    matrix 


    },sanitize.text.function = identity) 




# change row number for output table 
# only if new input table is created with create button 
row_number<-reactive({ 
    input$create_res # dependency 
    isolate(input$nres) 
}) 




# output table 
# object created when clicking on finish button 
# only dependent on finish button 
output_table<-reactive({ 

    input$finish_res # dependency 

    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    isolate(
    for (i in 1:isolate(row_number())) { 
     matrix[i,1] <- input[[paste0('element',i,'_',1)]] 
     matrix[i,2] <- input[[paste0('element',i,'_',2)]] 
     matrix[i,3] <- input[[paste0('element',i,'_',3)]] 
    } 
) 
    colnames(matrix) <- Col_entries 

    matrix 

}) 


# show output table 
output$check_table<-renderTable({ 
    if(input$finish_res == 0) return() #hide it on start 
    output_table() 
}) 

} 


runApp(list(ui = ui, server = server))