diff --git a/R/orNumeric.R b/R/orNumeric.R index 6b801dc..fd83518 100644 --- a/R/orNumeric.R +++ b/R/orNumeric.R @@ -12,7 +12,10 @@ orNumericUI <- function(id){ ns <- shiny::NS(id) shiny::tagList( - shiny::tagList(shinyjs::useShinyjs(), shiny::uiOutput(ns("label"))), + shiny::tagList(shinyjs::useShinyjs(), + shiny::singleton(shiny::tags$head(shiny::tags$link(rel = "stylesheet", type = "text/css", href = "wilson_www/styles.css"))), + shiny::uiOutput(ns("label")) + ), shiny::uiOutput(ns("options")), shiny::uiOutput(ns("slider")), shiny::uiOutput(ns("info")) @@ -89,142 +92,49 @@ orNumeric <- function(input, output, session, choices, value, label = "Column", } }) - css <- shiny::reactive({ - # range slider? - if(length(value.r()) > 1) { - shiny::req(input$options) - # span.irs-bar = range between points (inner) - # span.irs-line = range outside of points (outer) - # span.irs-slider.from = left point - # span.irs-slider.to = right point - # span.irs-from = text above left point - # span.irs-to = text above right point - # span.irs-min = left text above slider - # span.irs-max = right text above slider - # span.irs-single = joined texts above points - - # inner css - if(input$options == "inner") { - css <- shiny::HTML(paste0("") - # outer css - }else if(input$options == "outer") { - css <- shiny::HTML(paste0("") - } - #single slider - }else { - # span.irs-min = left text above slider - # span.irs-max = right text above slider - # span.irs-single = text above point - # span.irs-slider.single = point - # span.irs-bar = bar left side of point - # span.irs-bar-edge = left edge of bar - # span.irs-line = bar right side of point - - # default for < - less <- shiny::HTML(paste0("" - - if(any("<" == input$options)) { - less <- shiny::HTML(paste0("" - } - shiny::HTML(less, equal, greater) - } - }) - - # insert style for slider + # change css classes so slider visually matches options shiny::observe({ - # re-insert css if slider is re-rendered - min.r() - max.r() - - # escape . to get valid css selector - # TODO better validation - selector <- gsub(pattern = ".", replacement = "\\.", x = session$ns("slider-style"), fixed = TRUE) - selector2 <- gsub(pattern = ".", replacement = "\\.", x = session$ns("slider"), fixed = TRUE) - - if(length(value.r()) > 1) shiny::req(input$options) - shiny::removeUI( - selector = paste0("#", selector) - ) - - shiny::insertUI( - selector = paste0("#", selector2), - where = "afterBegin", - ui = css() - ) + # change css classes if slider is re-rendered + min.r() + max.r() + + if(length(value.r()) > 1){ + shiny::req(input$options) + + if(input$options == "inner") { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('outer')")) + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').addClass('inner')")) + } else if(input$options == "outer") { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('inner')")) + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').addClass('outer')")) + } + } else { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').addClass('empty')")) + + if(shiny::isTruthy(input$options)) { + if(any(input$options == ">")) { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').addClass('greater')")) + } else { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('greater')")) + } + + if(any(input$options == "=")) { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').addClass('equal')")) + } else { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('equal')")) + } + + if(any(input$options == "<")) { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').addClass('less')")) + } else { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('less')")) + } + } else { + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('greater')")) + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('equal')")) + shinyjs::runjs(paste0("$(document.getElementById('", session$ns("slider"),"')).find('span').removeClass('less')")) + } + } }) output$slider <- shiny::renderUI({ diff --git a/inst/www/styles.css b/inst/www/styles.css index dbbbaa8..0fd7231 100644 --- a/inst/www/styles.css +++ b/inst/www/styles.css @@ -8,6 +8,95 @@ opacity: 1; } -/* slider */ +/* slider +.irs-bar = range between points (inner)/ bar left side of point +.irs-bar-edge = left edge of bar +.irs-line = range outside of points (outer)/ bar right side of point +.irs-slider.single = single point +.irs-slider.from = left point +.irs-slider.to = right point +.irs-from = text above left point +.irs-to = text above right point +.irs-min = left text above slider +.irs-max = right text above slider +.irs-single = joined texts above points/ text above single point +*/ +/* ranged slider */ +.inner.irs-bar { + background: #428bca; + border-top: 1px solid #428bca; + border-bottom: 1px solid #428bca; +} + +.inner.irs-from, .inner.irs-to, .inner.irs-single { + background: #428bca; + color: #FFF; +} + +.inner.irs-line { + border: 1px solid #CCC; + background: linear-gradient(to bottom, #DDD -50%, #FFF 150%); +} + +.outer.irs-bar { + border: 1px solid #CCC; + background: linear-gradient(to bottom, #DDD -50%, #FFF 150%); +} + +.outer.irs-from, .outer.irs-to, .outer.irs-single { + background: rgba(0,0,0,0.1); + color: #333; +} + +.outer.irs-line { + background: #428bca; + border-top: 1px solid #428bca; + border-bottom: 1px solid #428bca; +} + +.outer.irs-min, .outer.irs-max { + background: #428bca; + color: #FFF; +} + +/* single slider */ +.less.irs-bar, .less.irs-bar-edge { + background: #428bca; + border-top: 1px solid #428bca; + border-bottom: 1px solid #428bca; +} + +.less.irs-min { + background: #428bca; + color: #FFF; +} + +.equal.irs-single { + background: #428bca; + color: #FFF; +} + +.greater.irs-line { + background: #428bca; + border-top: 1px solid #428bca; + border-bottom: 1px solid #428bca; +} + +.greater.irs-max { + background: #428bca; + color: #FFF; +} + +/* empty */ +.empty.irs-bar:not(.less), .empty.irs-bar-edge:not(.less) { + background: linear-gradient(to bottom, #DDD -50%, #FFF 150%); + border: 1px solid #CCC; + border-right: 0; +} + +.empty.irs-single:not(.equal) { + background: rgba(0,0,0,0.1); + color: #333; +} /* text input */