Adding javascript to my code

Hi friends,

I am trying to create cards in Dash with ability to flip 180 degrees on click. For that, I have Dash code, some CSS and 4 lines of javascript. Upon running, the app recognizes the CSS (stored in assets folder), but it doesn’t recognize javascript. Any ideas how to do this?

Here is the code:

Dash:

import dash
import dash_bootstrap_components as dbc
import dash_html_components as html
import dash_core_components as dcc
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

card = dbc.Container([

    dbc.Row(
    [
        dbc.Card(
		   dbc.CardImg(src="/assets/img_avatar3.png", alt="Avatar", style={"width":"100%"}),
		       className="front"), 

         dbc.Card(
		   dbc.CardImg(src="/assets/img_avatar2.png", alt="Avatar", style={"width":"100%"}),
		       className="back"), 

       
    ],
    className="card",
), ], 
    className="container",
	 )

cards = html.Div([card])

app.layout = cards


if __name__ == '__main__':
    app.run_server(debug=True)

CSS:

html,
body {
  height: 100%;
  margin: 0;
}
body {
  background: #00a5f7;
  display: -ms-flexbox;
  display: box;
  display: flex;
  -o-box-orient: vertical;
  flex-direction: column;
  -o-box-pack: center;
  justify-content: center;
  -o-box-align: center;
  align-items: center;
}
.container {
  width: 300px;
  height: 200px;
  position: relative;
  -webkit-perspective: 800px;
  -ms-perspective: 800px;
  perspective: 800px;
  border-radius: 4px;
}
.card {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transform-style: preserve-3d;
  transform-style: preserve-3d;
  transition: -webkit-transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275), -webkit-transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  border-radius: 6px;
  box-shadow: 0 6px 16px rgba(0,0,0,0.15);
  cursor: pointer;
}
.card div {
  position: absolute;
  width: 100%;
  height: 100%;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  border-radius: 6px;
  background: #fff;
  display: -ms-flexbox;
  display: box;
  display: flex;
  -o-box-pack: center;
  justify-content: center;
  -o-box-align: center;
  align-items: center;
  font: 16px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  color: #47525d;
}
.card .back {
  -webkit-transform: rotateY(180deg);
  transform: rotateY(180deg);
}
.card.flipped {
  -webkit-transform: rotateY(180deg);
  transform: rotateY(180deg);
}

Javascript:

$('.container').on('click', function () {
  $('.card').toggleClass('flipped');
});

Thanks!!! :slight_smile:

Hi @deebratforlife, I think you could use a clientside callback written in Javascript, as described in 📣 Dash 0.41.0 released.

Hi @deebratforlife,

I’m working on the same problem right now and have a hard time connecting the Javascript part with a Clientside Callback as suggested by @Emmanuelle. Did you solve the problem and could share your solution?

Many thanks!

In case somebody else stumbles upon the same problem: I solved it with the following approach:

Python -Dash

for card in  card_deck:
    @app.callback(
        Output(card, 'className'),
        [Input(card, 'n_clicks')]
    )
    def flip_card(n_clicks):
        if n_clicks is None:
            raise PreventUpdate
        elif (n_clicks % 2 == 0):
            return "cards_single"
        else:
            return "cards_single flip"

I have all my cards in a list called card_deck. For every element in this list, the above code adds a callback that listens to the click event on that element. in combination with the below CSS classes I was able to implement the desired behavior.

CSS:

.cards_single {
  background: lightslategray;
  display: flex;
  flex-direction: column;
  margin-top: 20px;
  border-radius: 16px;
  box-shadow: 0 5px 18px rgba(0, 0, 0, 0.6);
  cursor: pointer;
  text-align: center;
  -webkit-transition: transform 0.6s;
  transition: 0.6s;
  transform-style: preserve-3d;
}

.cards_single.flip {
  transform: rotateY(180deg);
  -webkit-transform: rotateY(180deg);
}

.cards_front, .cards_back {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  display: flex;
  flex-direction: column;
}
.cards_front {
  height: 100%;
  transform: rotateX(0deg);
  -webkit-transform: rotateX(0deg);
}

.cards_back {
  transform: rotateY(180deg);
  -webkit-transform: rotateY(180deg);
  position: absolute;
  text-align: center;
  right: 0;
  left: 0;
  color: #20263f;
}