Closed stelmath closed 3 years ago
Looks like the event listener is gone after the second rendering of the flipBox.
Initial run of the script and before selecting any name from the dropdown:
After selecting a name from the dropdown, other than the default one:
@DivadNojnarg I think I found the cause of this. I will make a PR pretty soon - please be aware. Thanks
I had to entirely rework the flipBox since it was causing a lot of issues (unable to devtools::check(), ...). Now eveything happens JS side, in a proper input binding. This allows to have a much more clean code (R side), an updateFlipBox
, know the state of the box at any time.
var flipBoxBinding = new Shiny.InputBinding();
$.extend(flipBoxBinding, {
find: function(scope) {
return $(scope).find(".flipbox");
},
// Given the DOM element for the input, return the value
getValue: function(el) {
return $(el).find('.card-front').hasClass('active');
},
setValue: function(el, value) {
var currentSide = $(el).find('.active');
if ($(el).data('rotate') === 'hover') {
if ($(currentSide).hasClass('card-front')) {
$(currentSide).trigger('mouseenter');
} else {
$(currentSide).trigger('mouseleave');
}
} else if ($(el).data('rotate') === 'click') {
$(currentSide).trigger('click');
}
},
// see updateAccordion
receiveMessage: function(el, data) {
this.setValue(el, data);
},
_clickOnFront: function(el) {
$(el).find('.card-front')
.css({
"-webkit-transform": "perspective(1600px) rotateY(-180deg)",
"transform": "perspective(1600px) rotateY(-180deg)"
})
.toggleClass('active');
$(el).find('.card-back')
.css({
"-webkit-transform": "perspective(1600px) rotateY(0deg)",
"transform": "perspective(1600px) rotateY(0deg)"
})
.toggleClass('active');
},
_clickOnBack: function(el) {
$(el).find('.card-front')
.css({"-webkit-transform": "", "transform": ""})
.toggleClass('active');
$(el).find('.card-back')
.css({"-webkit-transform": "", "transform": ""})
.toggleClass('active');
},
subscribe: function(el, callback) {
var self = this; // this will not work inside event listeners since it will
// refer to the element we clicked on and not the input binding object!!!
// use the data object to identify the trigger
if ($(el).data('rotate') === 'hover') {
$(el).find('.card-front').on('mouseenter', function() {
self._clickOnFront(el);
callback();
});
$(el).find('.card-back').on('mouseleave', function() {
self._clickOnBack(el);
callback();
});
} else if ($(el).data('rotate') === 'click') {
// click front
$(el).on('click', '.card-front', function(e) {
self._clickOnFront(el);
callback();
});
// click back
$(el).on('click', '.card-back', function(e) {
self._clickOnBack(el);
callback();
});
}
},
unsubscribe: function(el) {
$(el).off(".flipBoxBinding");
}
});
Shiny.inputBindings.register(flipBoxBinding, "flipbox-input");
Example:
remotes::install_github("RinteRface/shinydashboardPlus")
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
fluidRow(
column(
width = 6,
uiOutput("active_side"),
flipBox(
id = "myflipbox",
trigger = "hover",
width = 12,
front = div(
class = "text-center",
h1("Flip on hover"),
img(
src = "https://image.flaticon.com/icons/svg/149/149076.svg",
height = "300px",
width = "100%"
)
),
back = div(
class = "text-center",
height = "300px",
width = "100%",
h1("Flip on hover"),
p("More information....")
)
)
),
column(
width = 6,
uiOutput("active_side_2"),
flipBox(
id = "myflipbox2",
width = 12,
front = div(
class = "text-center",
h1("Flip on click"),
img(
src = "https://image.flaticon.com/icons/svg/149/149076.svg",
height = "300px",
width = "100%"
)
),
back = div(
class = "text-center",
height = "300px",
width = "100%",
h1("Flip on click"),
p("More information....")
)
)
)
)
)
),
server = function(input, output, session) {
output$active_side <- renderUI({
side <- if (input$myflipbox) "front" else "back"
dashboardBadge(side, color = "blue")
})
output$active_side_2<- renderUI({
side <- if (input$myflipbox2) "front" else "back"
dashboardBadge(side, color = "blue")
})
}
)
I'll check whether it still fail for your issue.
I adapted your previous example. The box is rotating as expected. Notice the absence of buttons to rotate. For now, rotation only occurs on click or on hover.
remotes::install_github("RinteRface/shinydashboardPlus")
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
fluidRow(
column(
width = 6,
align = "center",
selectInput('names', label= 'Pick a name to display the flipbox',
choices = c('mary', 'john', 'jane'), multiple = FALSE),
uiOutput('flip_box')
)
)
)
),
server = function(input, output) {
output$flip_box <- renderUI({
req(input$names)
# I need to use input values from various input widgets as parameter
# values in flipBox, that is why I am using the renderUI
# but the 'back side' button does not work on the second rendering
# of the flipbox, only the first time it renders
flipBox(
id = 1,
front = tagList(
h1(input$names),
"The first time this flipbox is displayed, the More button works fine.
But, when you select another name from the dropdown menu, and the flipbox is re-rendered,
the More button does not work",
fluidRow(
dashboardLabel("Label 1", status = "info"),
dashboardLabel("Label 2", status = "success"),
dashboardLabel("Label 3", status = "warning"),
dashboardLabel("Label 4", status = "primary"),
dashboardLabel("Label 5", status = "danger")
),
hr()
),
back = tagList(
column(
width = 12,
align = "center",
sliderInput(
"obs",
"Number of observations:",
min = 0,
max = 1000,
value = 500
)
),
plotOutput("distPlot")
))
})
output$distPlot <- renderPlot({
hist(rnorm(input$obs))
})
}
)
@DivadNojnarg I appreciate your time. Closing this, thanks!
Hello and thanks for the great package. I have seen other issue posts referring to the flip functionality of
flipBox
under the serverrenderUI
function.I have modified the manual example a bit to showcase the scenario that I am having:
As you can see, when you select a different name from the
selectInput
, let's say "John" then the box does not flip anymore. Any help with this? The flipping is a cool feature that I don't want to sacrifice.