2016-05-11 24 views
7

Używam błyszczącego szablonu deski rozdzielczej do generowania mojego interfejsu internetowego.Bezpośredni link do tabItem z błyszczącą deską rozdzielczą R

Chciałbym dynamicznie generować infobox, gdy obliczenia są zakończone z linkiem skierowanym do jednego z tabItems w dashboardBody.

Na przykład mogę umieścić w moim wyjściu tabItem1,

renderInfoBox({ 
    infoBox("Completed", 
    a("Computation Completed", href="#tabItem2"), 
    icon = icon("thumbs-o-up"), color = "green" 
) 
}) 

Ale problemem jest to, że po kliknięciu na link, to nic nie robi. Chciałbym, żeby przeskoczyło do tabItem2. Link href wydaje się prawidłowy po najechaniu na niego.

Dzięki!


Aktualizacja: Inny niż przy użyciu JavaScripts, wygląda przy użyciu actionLink i updateTabItems funkcje shinydashboard pakiet będzie działał jak dobrze.

Odpowiedz

12

Przepraszam za długotrwały przykład kodu, ale musiałem skopiować przykład z tabItems ze strony głównej błyszczącej tablicy.

Twoje podejście ma tylko kilka problemów. Po pierwsze, jeśli chcesz sprawdzić numer menuItems, zobaczysz, że rzeczywisty identyfikator karty nie jest tabItem2, ale shiny-tab-tabItem2. To, plus dodatkowy atrybut data-toggle="tab" w tagu a, wystarczyłoby do otwarcia żądanej zakładki. Snippet:

a("Computation Completed", href="#shiny-tab-tabItem2", "data-toggle" = "tab") 

Ale to ma swoje ograniczenia. Po pierwsze i najbardziej oczywiste, stan menuItem na pasku bocznym nie jest ustawiony na active. Wygląda to bardzo dziwnie i nie można być przekonanym, że przeniesiono do innej zakładki.

Po drugie i mniej oczywiste, jeśli słuchasz zmian w zakładkach (po stronie serwera), nie uzyskasz informacji o przełączniku tej karty. Wywoływane są one przez kliknięcie przycisku menuItem, a sama zakładka nie będzie raportować, jeśli jest widoczna lub ukryta.

Moje podejście polega więc na symulacji kliknięcia odpowiadającego menuItem, dzięki czemu wszystkie powyższe problemy zostaną rozwiązane.

przykładem Kod:

library(shiny) 
library(shinydashboard) 

ui <- shinyUI(
    dashboardPage(
    dashboardHeader(title = "Some Header"), 
    dashboardSidebar(
     sidebarMenu(
     menuItem("Computations", tabName = "tabItem1", icon = icon("dashboard")), 
     menuItem("Results", tabName = "tabItem2", icon = icon("th")) 
    ) 
    ), 

    dashboardBody(
     tabItems(
     tabItem(tabName = "tabItem1", 
      fluidRow(
      box(plotOutput("plot1", height = 250)), 

      box(
       title = "Controls", 
       sliderInput("slider", "Number of observations:", 1, 100, 50) 
      ) 
     ), 
      infoBoxOutput("out1") 
     ), 

     tabItem(tabName = "tabItem2", 
      h2("Widgets tab content") 
     ) 
    ) 
    ) 
) 
) 

server <- function(input, output){ 
    histdata <- rnorm(500) 

    output$plot1 <- renderPlot({ 
    data <- histdata[seq_len(input$slider)] 
    hist(data) 
    }) 

    output$out1 <- renderInfoBox({ 
    infoBox("Completed", 
     a("Computation Completed", onclick = "openTab('tabItem2')"), 
     tags$script(HTML(" 
     var openTab = function(tabName){ 
      $('a', $('.sidebar')).each(function() { 
      if(this.getAttribute('data-value') == tabName) { 
       this.click() 
      }; 
      }); 
     } 
     ")), 
     icon = icon("thumbs-o-up"), color = "green" 
    ) 
    }) 
} 

shinyApp(ui, server) 

Uwaga, że ​​jedyną ważną rzeczą jest własnością onclick, a nie href. Oznacza to, że każdy element div lub inny element może zostać użyty do utworzenia tego łącza. Możesz mieć tylko obrazek z kciukiem w górę za pomocą tego polecenia onclick.

Jeśli masz więcej pytań, prosimy o komentarz.

Pozdrawiam


Edit: Całe Infobox klikalne.

To jest odpowiedź do komentarza, którego autorem jest OmaymaS.Chodziło o to, aby kasa informacyjna była klikalnym kontenerem. Aby to osiągnąć, można zdefiniować nową funkcję, która tworzy nieco inny panel informacyjny. Skrzynka zwyczaj będzie wyglądał następująco:

customInfoBox <- function (title, tab = NULL, value = NULL, subtitle = NULL, icon = shiny::icon("bar-chart"), color = "aqua", width = 4, href = NULL, fill = FALSE) { 
    validateColor(color) 
    tagAssert(icon, type = "i") 
    colorClass <- paste0("bg-", color) 
    boxContent <- div(class = "info-box", class = if (fill) colorClass, 
     onclick = if(!is.null(tab)) paste0("$('.sidebar a')).filter(function() { return ($(this).attr('data-value') == ", tab, ")}).click()"), 
     span(class = "info-box-icon", class = if (!fill) colorClass, icon), 
     div(class = "info-box-content", 
      span(class = "info-box-text", title), 
      if (!is.null(value)) span(class = "info-box-number", value), 
      if (!is.null(subtitle)) p(subtitle) 
     ) 
    ) 
    if (!is.null(href)) boxContent <- a(href = href, boxContent) 
    div(class = if (!is.null(width)) paste0("col-sm-", width), boxContent) 
} 

Ten kod jest skopiowany z oryginalnej definicji infoBox funkcji i tylko linia z onclick jest nowy. Dodałem także funkcję openTab (z kilkoma skurczami) bezpośrednio w pojemniku, tak że nie musisz się martwić, gdzie umieścić tę funkcję wewnątrz widoku. Być może czuję się trochę przeładowany. To niestandardowe pole informacyjne może być używane dokładnie tak samo, jak domyślne i jeśli zostanie przekazany dodatkowy argument tab, zostanie dodany link do paska bocznego.

+0

To jest bardzo miłe! Bardzo to doceniam. – athlonshi

+0

Co jeśli chcę zastosować go do całego infoboxu, czyli do dowolnej części infoboxu. Nie jestem pewien, co to jest tag, próbowałem się wymeldować, ale nie działał. jakaś wskazówka? – OmaymaS

+1

@OmaymaS Wierzę (bez wypróbowania tego), że możesz po prostu przenieść właściwość 'onclick' z' a'-tagu jedną linię do znacznika 'infoBox'. To powinno dodać funkcjonalność do całego kontenera infobox. –

Powiązane problemy