# Python library called dash draggable cannot use pattern-matching-callback

**URL:** <https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499>\
**Category:** Dash Python\
**Tags:** question\
**Created:** [November 2, 2022, 3:24pm UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499 "2022-11-02T15:24:00Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Osako](https://avatars.discourse-cdn.com/v4/letter/o/ac91a4/32.png) [@Osako](https://community.plotly.com/u/Osako)\
**Post date:** [November 2, 2022, 3:24pm UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/1 "2022-11-02T15:24:00Z")

</div>

Hello  
I’m using dash draggable, but as per the github issue, I can’t use it for pattern-matching-callback.  
[dash draggable issue](https://github.com/MehdiChelh/dash-draggable/issues/10)  
Do you know of any good remedies?

---

<div class="post-metadata">

**Author:** ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)\
**Post date:** [November 2, 2022, 5:15pm UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/2 "2022-11-02T17:15:11Z")

</div>

Hello @Osako,

You could use css to achieve this outcome.

Also, could. you please provide an example of the callback you are running into the issue? I see that issue has just the code to make the draggable elements.

---

<div class="post-metadata">

**Author:** ![Osako](https://avatars.discourse-cdn.com/v4/letter/o/ac91a4/32.png) [@Osako](https://community.plotly.com/u/Osako)\
**Post date:** [November 3, 2022, 9:16am UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/3 "2022-11-03T09:16:41Z")

</div>

Thank you for the reply  
This is example(AnnMarieW’s reply)  
[example](https://community.plotly.com/t/pattern-call-backs-regarding-adding-dynamic-graphs/40724/3)

---

<div class="post-metadata">

**Author:** ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)\
**Post date:** [November 3, 2022, 9:24am UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/4 "2022-11-03T09:24:32Z")

</div>

That example doesn’t use draggable.

Please provide an MRE:

> [@How to write a Minimal Reproducible Example (MRE)](https://community.plotly.com/t/how-to-write-a-minimal-reproducible-example-mre/61502):
>
> Adding a minimal reproducible example to your questions will help attract community members to answer your question. The goal of writing a MRE is to allow other members of the community to run the code on their computers and “reproduce” the error, so that they can best help you. Please make sure that your MRE includes data and that the code is correctly pre-formatted. To preformat, copy and paste the code in your post and then click on \</\> (Preformatted text), as shown on the image:

---

<div class="post-metadata">

**Author:** ![Osako](https://avatars.discourse-cdn.com/v4/letter/o/ac91a4/32.png) [@Osako](https://community.plotly.com/u/Osako)\
**Post date:** [November 3, 2022, 9:37am UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/5 "2022-11-03T09:37:38Z")

</div>

Sorry  
Here is the code.  
I am unable to resize the draggable by the number of columns.  
There is also a github issue with the same issue.

```auto
import dash
from dash.dependencies import Input, Output, State, ALL, MATCH
import dash_html_components as html
import dash_core_components as dcc
import plotly.express as px
import json
import dash_draggable

df = px.data.gapminder()

app = dash.Dash( __name__ )

app.layout = html.Div(
    [
        html.Div(
            children=[
                dcc.Dropdown(
                    options=[{"label": i, "value": i} for i in df.country.unique()],
                    value="Canada",
                    id="country",
                    style={"display": "inline-block", "width": 200},
                ),
                html.Button(
                    "Add Chart",
                    id="add-chart",
                    n_clicks=0,
                    style={"display": "inline-block"},
                ),
            ],
        ),
        html.Div(children=[dash_draggable.GridLayout (id ="draggable",
                                                       children=[])]),
    ] ,
)

def create_figure(column_x, column_y, country):
    chart_type = px.line if column_x == "year" else px.scatter
    return (
        chart_type(df.query("country == '{}'".format(country)), x=column_x, y=column_y,)
        .update_layout(
            title="{} {} vs {}".format(country, column_x, column_y),
            margin_l=10,
            margin_r=0,
            margin_b=30,
        )
        .update_xaxes(title_text="")
        .update_yaxes(title_text="")
    )

@app.callback(
    Output("draggable", "children"),
    [
        Input("add-chart", "n_clicks"),
        Input({"type": "dynamic-delete", "index": ALL}, "n_clicks"),
    ],
    [State("draggable", "children"), State("country", "value")],
)
def display_dropdowns(n_clicks, _, children, country):
    default_column_x = "year"
    default_column_y = "gdpPercap"

    input_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]
    if "index" in input_id:
        delete_chart = json.loads(input_id)["index"]
        children = [
            chart
            for chart in children
            if "'index': " + str(delete_chart) not in str(chart)
        ]
    else:
        new_element = html.Div(
            style={
                "width": "23%",
                "display": "inline-block",
                "outline": "thin lightgrey solid",
                "padding": 10,
            },
            children=[
                html.Button(
                    "X",
                    id={"type": "dynamic-delete", "index": n_clicks},
                    n_clicks=0,
                    style={"display": "block"},
                ),
                dcc.Graph(
                    id={"type": "dynamic-output", "index": n_clicks},
                    style={"height": 300},
                    figure=create_figure(default_column_x, default_column_y, country),
                ),
                dcc.Dropdown(
                    id={"type": "dynamic-dropdown-x", "index": n_clicks},
                    options=[{"label": i, "value": i} for i in df.columns],
                    value=default_column_x,
                ),
                dcc.Dropdown(
                    id={"type": "dynamic-dropdown-y", "index": n_clicks},
                    options=[{"label": i, "value": i} for i in df.columns],
                    value=default_column_y,
                ),
            ],
        )
        children.append(new_element)
    return children

@app.callback(
    Output({"type": "dynamic-output", "index": MATCH}, "figure"),
    [
        Input({"type": "dynamic-dropdown-x", "index": MATCH}, "value"),
        Input({"type": "dynamic-dropdown-y", "index": MATCH}, "value"),
        Input("country", "value"),
    ],
)
def display_output(column_x, column_y, country):
    return create_figure(column_x, column_y, country)

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

```

---

<div class="post-metadata">

**Author:** ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)\
**Post date:** [November 3, 2022, 10:16am UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/6 "2022-11-03T10:16:54Z")

</div>

Hmm, mine seems to work.

Make sure you’ve updated dash, the version is now up to 2.6.2.

Here is the slightly modified code for 2.6.2.

```auto
import dash
from dash import Input, Output, State, ALL, MATCH, dcc, html
import plotly.express as px
import json
import dash_draggable

df = px.data.gapminder()

app = dash.Dash( __name__ )

app.layout = html.Div(
    [
        html.Div(
            children=[
                dcc.Dropdown(
                    options=[{"label": i, "value": i} for i in df.country.unique()],
                    value="Canada",
                    id="country",
                    style={"display": "inline-block", "width": 200},
                ),
                html.Button(
                    "Add Chart",
                    id="add-chart",
                    n_clicks=0,
                    style={"display": "inline-block"},
                ),
            ],
        ),
        html.Div(children=[dash_draggable.GridLayout (id ="draggable",
                                                       children=[])]),
    ] ,
)

def create_figure(column_x, column_y, country):
    chart_type = px.line if column_x == "year" else px.scatter
    return (
        chart_type(df.query("country == '{}'".format(country)), x=column_x, y=column_y,)
        .update_layout(
            title="{} {} vs {}".format(country, column_x, column_y),
            margin_l=10,
            margin_r=0,
            margin_b=30,
        )
        .update_xaxes(title_text="")
        .update_yaxes(title_text="")
    )

@app.callback(
    Output("draggable", "children"),
    [
        Input("add-chart", "n_clicks"),
        Input({"type": "dynamic-delete", "index": ALL}, "n_clicks"),
    ],
    [State("draggable", "children"), State("country", "value")],
)
def display_dropdowns(n_clicks, _, children, country):
    default_column_x = "year"
    default_column_y = "gdpPercap"

    input_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]
    if "index" in input_id:
        delete_chart = json.loads(input_id)["index"]
        children = [
            chart
            for chart in children
            if "'index': " + str(delete_chart) not in str(chart)
        ]
    else:
        new_element = html.Div(
            style={
                "width": "23%",
                "display": "inline-block",
                "outline": "thin lightgrey solid",
                "padding": 10,
            },
            children=[
                html.Button(
                    "X",
                    id={"type": "dynamic-delete", "index": n_clicks},
                    n_clicks=0,
                    style={"display": "block"},
                ),
                dcc.Graph(
                    id={"type": "dynamic-output", "index": n_clicks},
                    style={"height": 300},
                    figure=create_figure(default_column_x, default_column_y, country),
                ),
                dcc.Dropdown(
                    id={"type": "dynamic-dropdown-x", "index": n_clicks},
                    options=[{"label": i, "value": i} for i in df.columns],
                    value=default_column_x,
                ),
                dcc.Dropdown(
                    id={"type": "dynamic-dropdown-y", "index": n_clicks},
                    options=[{"label": i, "value": i} for i in df.columns],
                    value=default_column_y,
                ),
            ],
        )
        children.append(new_element)
    return children

@app.callback(
    Output({"type": "dynamic-output", "index": MATCH}, "figure"),
    [
        Input({"type": "dynamic-dropdown-x", "index": MATCH}, "value"),
        Input({"type": "dynamic-dropdown-y", "index": MATCH}, "value"),
        Input("country", "value"),
    ],
)
def display_output(column_x, column_y, country):
    return create_figure(column_x, column_y, country)

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

```

---

<div class="post-metadata">

**Author:** ![Osako](https://avatars.discourse-cdn.com/v4/letter/o/ac91a4/32.png) [@Osako](https://community.plotly.com/u/Osako)\
**Post date:** [November 3, 2022, 10:25am UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/7 "2022-11-03T10:25:56Z")

</div>

Sorry for my poor explanation.  
The code works, but the chart is very small when I press the add chart button. Changing nrow or ncol doesn’t make it bigger.  
 ![EXAMPLE](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/5/3/531576ce64e26bb065c6e2cde29aac964dd9025d.jpeg)  
I think this is because the dict type id cannot be read.

---

<div class="post-metadata">

**Author:** ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)\
**Post date:** [November 3, 2022, 11:12am UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/8 "2022-11-03T11:12:28Z")

</div>

The draggable div style is being automatically defined as this:

```auto
transform: translate(10px, 10px); width: 89px; height: 30px; position: absolute;

```

No changes I made even to the id fixed the issue that you are encountering. Dont know why it is defaulting to this. Also, remove your width argument from the div, its making the chart not take up the full width when expanded.

---

<div class="post-metadata">

**Author:** ![Osako](https://avatars.discourse-cdn.com/v4/letter/o/ac91a4/32.png) [@Osako](https://community.plotly.com/u/Osako)\
**Post date:** [November 3, 2022, 12:54pm UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/9 "2022-11-03T12:54:30Z")

</div>

Thank you for your reply. I give up on using dash draggable and try what is in this [article].([Drag and drop cards - #2 by RenaudLN](https://community.plotly.com/t/drag-and-drop-cards/42480/2))

---

<div class="post-metadata">

**Author:** ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)\
**Post date:** [November 3, 2022, 12:59pm UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/10 "2022-11-03T12:59:41Z")

</div>

Nice, I do something similar using Js not react and mine won’t snap to a grid.

Let me know if you have issues with the pattern matching for the clientside callback.

---

<div class="post-metadata">

**Author:** ![Osako](https://avatars.discourse-cdn.com/v4/letter/o/ac91a4/32.png) [@Osako](https://community.plotly.com/u/Osako)\
**Post date:** [November 4, 2022, 4:32pm UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/11 "2022-11-04T16:32:11Z")

</div>

Drag could! !  
But there is a problem.  
I have created a draggable button with a checkbox. But I can’t control the drag. (If I remove the check button again, it always drags.) I think something is wrong in the js file.

scripts.js

```auto
if (!window.dash_clientside) {
    window.dash_clientside = {};
}
window.dash_clientside.clientside = {
    make_draggable: function(id,value) {
        console.log(value)
        if (value =='draggable'){
            setTimeout(function() {
                var el = document.getElementById(id)
                window.console.log(el)
                dragula([el])
            }, 1)}
        return window.dash_clientside.no_update
    }
}

```

dragula.css

```auto
.gu-mirror {
    position: fixed !important;
    margin: 0 !important;
    z-index: 9999 !important;
    opacity: 0.8;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
    filter: alpha(opacity=80);
  }
  .gu-hide {
    display: none !important;
  }
  .gu-unselectable {
    -webkit-user-select: none !important;
    -moz-user-select: none !important;
    -ms-user-select: none !important;
    user-select: none !important;
  }
  .gu-transit {
    opacity: 0.2;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
    filter: alpha(opacity=20);
  }

```

app.py

```auto
import dash
from dash.dependencies import Input, Output, State, ALL, MATCH,ClientsideFunction
import dash_html_components as html
import dash_core_components as dcc
import plotly.express as px
import json
import dash_bootstrap_components as dbc
df = px.data.gapminder()

app = dash.Dash(
    __name__ ,
    external_scripts=["https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.min.js"],
    external_stylesheets=[dbc.themes.BOOTSTRAP]
)

app.layout = html.Div(
    [
        html.Div(
            children=[
                dcc.Dropdown(
                    options=[{"label": i, "value": i} for i in df.country.unique()],
                    value="Canada",
                    id="country",
                    style={"display": "inline-block", "width": 200},
                ),
                html.Button(
                    "Add Chart",
                    id="add-chart",
                    n_clicks=0,
                    style={"display": "inline-block"},
                ),
                dcc.Checklist (
                    id = "checklist",
                    options = [
                        {"label":"draggable","value":"draggable"}]),
            ]
        ),
        html.Div(id="container",className='con',children=[]),
    ]
)

#
def create_figure(column_x, column_y, country):
    chart_type = px.line if column_x == "year" else px.scatter
    return (
        chart_type(df.query("country == '{}'".format(country)), x=column_x, y=column_y,)
        .update_layout(
            title="{} {} vs {}".format(country, column_x, column_y),
            margin_l=10,
            margin_r=0,
            margin_b=30,
        )
        .update_xaxes(title_text="")
        .update_yaxes(title_text="")
    )

@app.callback(
    Output("container", "children"),
    [
        Input("add-chart", "n_clicks"),
        Input({"type": "dynamic-delete", "index": ALL}, "n_clicks"),
    ],
    [State("container", "children"), State("country", "value")],
)
def display_dropdowns(n_clicks, _, children, country):
    default_column_x = "year"
    default_column_y = "gdpPercap"

    input_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]
    if "index" in input_id:
        delete_chart = json.loads(input_id)["index"]
        children = [
            chart
            for chart in children
            if "'index': " + str(delete_chart) not in str(chart)
        ]
    else:
        new_element = html.Div(
            style={
                "width": "23%",
                "display": "inline-block",
                "outline": "thin lightgrey solid",
                "padding": 10,
            },
            children=[
                html.Button(
                    "X",
                    id={"type": "dynamic-delete", "index": n_clicks},
                    n_clicks=0,
                    style={"display": "block"},
                ),
                dcc.Graph(
                    id={"type": "dynamic-output", "index": n_clicks},
                    style={"height": 300},
                    figure=create_figure(default_column_x, default_column_y, country),
                ),
                dcc.Dropdown(
                    id={"type": "dynamic-dropdown-x", "index": n_clicks},
                    options=[{"label": i, "value": i} for i in df.columns],
                    value=default_column_x,
                ),
                dcc.Dropdown(
                    id={"type": "dynamic-dropdown-y", "index": n_clicks},
                    options=[{"label": i, "value": i} for i in df.columns],
                    value=default_column_y,
                ),
            ],
        )
        children.append(new_element)
    return children
#
#
@app.callback(
    Output({"type": "dynamic-output", "index": MATCH}, "figure"),
    [
        Input({"type": "dynamic-dropdown-x", "index": MATCH}, "value"),
        Input({"type": "dynamic-dropdown-y", "index": MATCH}, "value"),
        Input("country", "value"),
    ],
)
def display_output(column_x, column_y, country):
    return create_figure(column_x, column_y, country)

app.clientside_callback(
    ClientsideFunction(namespace="clientside", function_name="make_draggable"),
    Output("container", "data-drag"),
    [Input("container", "id"),
     Input("checklist","value")],
)

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

```

---

<div class="post-metadata">

**Author:** ![Strider](https://avatars.discourse-cdn.com/v4/letter/s/aeb1de/32.png) [@Strider](https://community.plotly.com/u/Strider)\
**Post date:** [December 15, 2023, 6:55am UTC](https://community.plotly.com/t/python-library-called-dash-draggable-cannot-use-pattern-matching-callback/69499/12 "2023-12-15T06:55:42Z")

</div>

Hi, I know this is an old thread, but I would like to provide a solution that I found to this problem of dash-draggable generating very small components. The issue seems to be that the default height of each component has been set to 30 pixels, and you need to dive into the dash\_draggable.min.js file to change this value. For the ResponsiveGridLayout, this value can be found at the bottom of this file, as highlighted in the picture. In the picture, I have changed the value to 150, and now the newly generated components are no longer a thin strip. Do note that changing this value also changes the minimum dimensions of the component itself - i.e. by changing to value to 150, the minimum height becomes 150 pixels as well. It’s a bit of compromise in this sense. I believe the height value for GridLayout can be found just slightly north of the highlighted text - just search for the value “30”.

After that, I realised that this value also corresponds to “height” argument for ResponsiveGridLayout. This is a bit strange considering that the description for the “height” arugment is “height of the rows of the grid (in pixels).” and not the size of the added child components according to their documentation…  
Either way, I hope that this will be useful to anyone trying to find a solution to this problem!

 ![image](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/1/b/1bd82315d2556182e2bcb80227fb58f6fd594d56.png)  
 ![image](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/c/7/c7788ab812bcc6be01afa70f6259751451ef05ea.png)  
 ![image](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/7/0/70f3e1926526b1c151c907df4ed61b4b38c95645.png)
