Dragging of panels

19 Dec 202224 minutes to read

The Dashboard Layout component is provided with dragging functionality to drag and reorder the panels within the layout. While dragging a panel, a holder will be highlighted below the panel indicating the panel placement on panel drop. This helps the user to decide whether to place the panel in the current position or revert to previous position without disturbing the layout.

If one or more panels collide while dragging, then the colliding panels will be pushed towards the left or right or top or bottom direction where an adaptive space for the collided panel is available. The position changes of these collided panels will be updated dynamically during dragging of a panel, so the user can conclude whether to place the panel in the current position or not.

While dragging a panel in Dashboard layout the following dragging events will be triggered,

  • dragStart - Triggers when panel drag starts
  • drag - Triggers when panel is being dragged
  • dragStop - Triggers when panel drag stops

The following sample demonstrates dragging and pushing of panels. For example, while dragging the panel 0 over panel 1, these panels get collided and push the panel 1 towards the feasible direction, so that the panel 0 gets placed in the panel 1 position.

<div>
    <!--  Dashboardlayout element declaration -->
    <ejs-dashboardlayout id="dashboard_layout" columns="5" cellSpacing="@Model.cellSpacing" drag="onDrag" dragStart="onDragStart" dragStop="onDragStop">
        <e-dashboardlayout-panels>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="0" col="0" content="<div>0</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="3" sizeY="2" row="0" col="1" content="<div>1</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="3" row="0" col="4" content="<div>2</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="1" col="0" content="<div>3</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="2" sizeY="1" row="2" col="0" content="<div>4</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="2" col="2" content="<div>5</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="2" col="3" content="<div>6</div>">
            </e-dashboardlayout-panel>
        </e-dashboardlayout-panels>
    </ejs-dashboardlayout>
</div>
<!-- end of dashboardlayout element -->
<script>
function onDrag(args) {
    console.log("Dragging");
}
function onDragStart(args) {
    console.log("Drag Start");
}
function onDragStop(args) {
    console.log("Drag Stop");
}
</script>
<style>
     /* DashboardLayout element styles  */
    #dashboard_layout .e-panel .e-panel-container {
        vertical-align: middle;
        font-weight: 600;
        font-size: 20px;
        text-align: center;
        line-height: 90px;
    }
</style>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication.Controllers
{
    public class HomeController : Controller
    {
        public class spacingModel
        {
            public double[] cellSpacing { get; set; }
        }
        public ActionResult Index()
        {
            spacingModel modelValue = new spacingModel();
            modelValue.cellSpacing = new double[] { 10, 10 };
            return View(modelValue);
        }
    }
}

Drag and Drop

Customizing the dragging handler

Initially, the complete panel will act as a handler for dragging the panel such that the dragging action occurs on clicking anywhere over a panel. However, this dragging handler for the panels can be customized using the draggableHandle property to restrict the dragging action within a particular element in the panel.

The following sample demonstrates customizing the dragging handler of the panels where the dragging action of panel occurs only with the header of the panel.

<div>
    <!--  Dashboardlayout element declaration -->
    <ejs-dashboardlayout id="dashboard_default" columns="6" draggableHandle=".e-panel-header" cellSpacing="@Model.cellSpacing">
        <e-dashboardlayout-panels>
            <e-dashboardlayout-panel id="Panel1" sizeX="3" sizeY="2" row="0" col="3" header="<div class='header'>Last year sales comparison</div><span class='handler e-icons burg-icon'></span>" content="#column">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel id="Panel2" sizeX="3" sizeY="2" row="0" col="3" header="<div class='header'>Mobile browsers usage</div><span class='handler e-icons burg-icon'></span>" content="#pie1">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel id="Panel3" sizeX="3" sizeY="2" row="1" col="0" header="<div class='header'>Sales increase percentage</div><span class='handler e-icons burg-icon'></span>" content="#line">
            </e-dashboardlayout-panel>
        </e-dashboardlayout-panels>
    </ejs-dashboardlayout>
</div>
<!-- end of dashboardlayout element -->
<div id="column">
     <!--  Column Chart element declaration -->
    <ejs-chart id="columnChart" height="162px">          
        <e-chart-primaryxaxis valueType="Category"></e-chart-primaryxaxis>
        <e-series-collection>
            <e-series dataSource="ViewBag.chartSource" xName='month' yName='sales' type="@Syncfusion.EJ2.Charts.ChartSeriesType.Column"> 
            </e-series>
        </e-series-collection>
    </ejs-chart>
    <!-- end of chart element -->
</div>

<div id="line">
    <!--  Line Chart element declaration -->
    <ejs-chart id="lineChart" height="162px">
        <e-chart-primaryxaxis valueType="Category"></e-chart-primaryxaxis>
        <e-series-collection>
            <e-series dataSource="ViewBag.lineSource" xName='x' yName='y' type="@Syncfusion.EJ2.Charts.ChartSeriesType.Line">
            </e-series>
        </e-series-collection>
    </ejs-chart>
    <!-- end of chart element -->
</div>

<div id="pie1">
    <!--  Pie Chart element declaration -->
    <ejs-accumulationchart id="pieChart1" enableAnimation="false" enableSmartLabels="true" height="162px">
        <e-accumulationchart-tooltipsettings enable="true" format="${point.x} : <b>${point.y}%</b>"></e-accumulationchart-tooltipsettings>
        <e-accumulationchart-legendsettings visible="false">
        </e-accumulationchart-legendsettings>
        <e-accumulation-series-collection>
            <e-accumulation-series dataSource="ViewBag.pieSource1" xName="x" yName="y" radius="70%" name="Browser">
                <e-accumulationseries-datalabel name="text" visible="true" position="Inside">
                </e-accumulationseries-datalabel>
            </e-accumulation-series>
        </e-accumulation-series-collection>
    </ejs-accumulationchart>
    <!-- end of chart element -->
</div>

<style>
    /* DashboardLayout element styles  */
    .e-dashboard-layout.e-control .e-panel .e-panel-container .e-panel-header {
        color: rgba(0, 0, 0, 0.61);
    }

    .e-panel .e-header-text {
        padding: 12px 0 12px 0;
    }

    #dashboard .e-panel-container .e-panel-header {
        border-bottom: 1px solid #888383;
    }

    .e-dashboard-layout.e-control .e-panel:hover {
        border: 0px;
    }

    .e-dashboard-layout.e-control .e-panel .e-panel-header {
        font-size: 15px;
        font-weight: 500;
        height: 37px;
        padding: 10px;
        vertical-align: middle;
        /* text-align: left; */
        border-bottom: 0.5px solid rgba(0, 0, 0, .125);
    }

    .e-panel-header {
        padding: 10px;
        margin-bottom: 0;
        background-color: rgba(0, 0, 0, .03);
    }

    .e-dashboard-layout.e-control .e-panel .e-panel-header {
        height: 30px
    }

    .e-dashboard-layout.e-control .e-panel .e-panel-header div {
        text-align: center;
    }

    .header {
        padding: 5px;
        display: inline-block;
    }

    .e-panel-content {
        height: 162px;
    }
    /* custom generated icons styles */
    @@font-face {
        font-family: 'e-icons';
        src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMjciQ6oAAAEoAAAAVmNtYXBH1Ec8AAABsAAAAHJnbHlmKcXfOQAAAkAAAAg4aGVhZBLt+DYAAADQAAAANmhoZWEHogNsAAAArAAAACRobXR4LvgAAAAAAYAAAAAwbG9jYQukCgIAAAIkAAAAGm1heHABGQEOAAABCAAAACBuYW1lR4040wAACngAAAJtcG9zdEFgIbwAAAzoAAAArAABAAADUv9qAFoEAAAA//UD8wABAAAAAAAAAAAAAAAAAAAADAABAAAAAQAAlbrm7l8PPPUACwPoAAAAANfuWa8AAAAA1+5ZrwAAAAAD8wPzAAAACAACAAAAAAAAAAEAAAAMAQIAAwAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQPqAZAABQAAAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA4QLhkANS/2oAWgPzAJYAAAABAAAAAAAABAAAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAAAAAAgAAAAMAAAAUAAMAAQAAABQABABeAAAADgAIAAIABuEC4QnhD+ES4RvhkP//AADhAuEJ4QvhEuEa4ZD//wAAAAAAAAAAAAAAAAABAA4ADgAOABYAFgAYAAAAAQACAAYABAADAAgABwAKAAkABQALAAAAAAAAAB4AQABaAQYB5gJkAnoCjgKwA8oEHAAAAAIAAAAAA+oDlQAEAAoAAAEFESERCQEVCQE1AgcBZv0mAXQB5P4c/g4Cw/D+lwFpAcP+s24BTf6qbgAAAAEAAAAAA+oD6gALAAATCQEXCQEHCQEnCQF4AYgBiGP+eAGIY/54/nhjAYj+eAPr/ngBiGP+eP54YwGI/nhjAYgBiAAAAwAAAAAD6gOkAAMABwALAAA3IRUhESEVIREhFSEVA9b8KgPW/CoD1vwq6I0B64wB640AAAEAAAAAA+oD4QCaAAABMx8aHQEPDjEPAh8bIT8bNS8SPxsCAA0aGhgMDAsLCwoKCgkJCQgHBwYGBgUEBAMCAgECAwUFBggICQoLCwwMDg0GAgEBAgIDBAMIBiIdHh0cHBoZFhUSEAcFBgQDAwEB/CoBAQMDBAUGBw8SFRYYGhsbHB0cHwsJBQQEAwIBAQMEDg0NDAsLCQkJBwYGBAMCAQEBAgIDBAQFBQYGBwgICAkJCgoKCwsLDAwMGRoD4gMEBwQFBQYGBwgICAkKCgsLDAwNDQ4ODxAQEBEWFxYWFhYVFRQUExIRERAOFxMLCggIBgYFBgQMDAwNDg4QDxERERIJCQkKCQkJFRQJCQoJCQgJEhERERAPDw4NDQsMBwgFBgYICQkKDAwODw8RERMTExUUFhUWFxYWFxEQEBAPDg4NDQwMCwsKCgkICAgHBgYFBQQEBQQAAAAAAwAAAAAD8wPzAEEAZQDFAAABMx8FFREzHwYdAg8GIS8GPQI/BjM1KwEvBT0CPwUzNzMfBR0CDwUrAi8FPQI/BTMnDw8fFz8XLxcPBgI+BQQDAwMCAT8EBAMDAwIBAQIDAwMEBP7cBAQDAwMCAQECAwMDBAQ/PwQEAwMDAgEBAgMDAwQE0AUEAwMDAgEBAgMDAwQFfAUEAwMDAgEBAgMDAwQFvRsbGRcWFRMREA4LCQgFAwEBAwUHCgsOEBETFRYXGRocHR4eHyAgISIiISAgHx4eHRsbGRcWFRMREA4LCQgFAwEBAwUHCgsOEBETFRYXGRsbHR4eHyAgISIiISAgHx4eAqYBAgIDBAQE/rMBAQEDAwQEBGgEBAQDAgIBAQEBAgIDBAQEaAQEBAMDAQEB0AECAwMDBAVoBAQDAwMCAeUBAgIEAwQEaAUEAwMDAgEBAgMDAwQFaAQEAwQCAgElERMVFhcZGhwdHh4fICAhIiIhICAfHh4dGxsZFxYVExEQDgsJCAUDAQEDBQcKCw4QERMVFhcZGxsdHh4fICAhIiIhICAfHh4dHBoZFxYVExEQDgsKBwUDAQEDBQcKCw4AAAIAAAAAA9MD6QALAE8AAAEOAQcuASc+ATceAQEHBgcnJgYPAQYWHwEGFBcHDgEfAR4BPwEWHwEeATsBMjY/ATY3FxY2PwE2Ji8BNjQnNz4BLwEuAQ8BJi8BLgErASIGApsBY0tKYwICY0pLY/7WEy4nfAkRBWQEAwdqAwNqBwMEZAURCXwnLhMBDgnICg4BEy4mfQkRBGQFAwhpAwNpCAMFZAQSCH0mLhMBDgrICQ4B9UpjAgJjSkpjAgJjAZWEFB4yBAYIrggSBlIYMhhSBhIIrggFAzIfE4QJDAwJhBQeMgQGCK4IEgZSGDIYUgYSCK4IBQMyHxOECQwMAAEAAAAAAwED6gAFAAAJAicJAQEbAef+FhoBzf4zA+v+Ff4VHwHMAc0AAAAAAQAAAAADAQPqAAUAAAEXCQEHAQLlHf4zAc0a/hYD6x7+M/40HwHrAAEAAAAAA/MD8wALAAATCQEXCQE3CQEnCQENAY7+cmQBjwGPZP5yAY5k/nH+cQOP/nH+cWQBjv5yZAGPAY9k/nEBjwAAAwAAAAAD8wPzAEAAgQEBAAAlDw4rAS8dPQE/DgUVDw4BPw47AR8dBRUfHTsBPx09AS8dKwEPHQL1DQ0ODg4PDw8QEBAQERERERUUFBQTExITEREREBAPDw0ODAwLCwkJCAcGBgQEAgIBAgIEAwUFBgYHBwkICQoCygECAgQDBQUGBgcHCQgJCv3QDQ0ODg4PDw8QEBAQERERERUUFBQTExITEREREBAPDw0ODAwLCwkJCAcGBgQEAgL8fgIDBQUHCAkKCwwNDg8PERESExQUFRYWFhgXGBkZGRoaGRkZGBcYFhYWFRQUExIREQ8PDg0MCwoJCAcFBQMCAgMFBQcICQoLDA0ODw8RERITFBQVFhYWGBcYGRkZGhoZGRkYFxgWFhYVFBQTEhERDw8ODQwLCgkIBwUFAwLFCgkICQcHBgYFBQMEAgIBAgIEBAYGBwgJCQsLDAwODQ8PEBARERETEhMTFBQUFREREREQEBAQDw8PDg4ODQ31ERERERAQEBAPDw8ODg4NDQIwCgkICQcHBgYFBQMEAgIBAgIEBAYGBwgJCQsLDAwODQ8PEBARERETEhMTFBQUFRoZGRkYFxgWFhYVFBQTEhERDw8ODQwLCgkIBwUFAwICAwUFBwgJCgsMDQ4PDxEREhMUFBUWFhYYFxgZGRkaGhkZGRgXGBYWFhUUFBMSEREPDw4NDAsKCQgHBQUDAgIDBQUHCAkKCwwNDg8PERESExQUFRYWFhgXGBkZGQAAAQAAAAAD6gPqAEMAABMhHw8RDw8hLw8RPw6aAswNDgwMDAsKCggIBwUFAwIBAQIDBQUHCAgKCgsMDAwODf00DQ4MDAwLCgoICAcFBQMCAQECAwUFBwgICgoLDAwMDgPrAQIDBQUHCAgKCgsLDA0NDv00Dg0NDAsLCgoICAcFBQMCAQECAwUFBwgICgoLCwwNDQ4CzA4NDQwLCwoKCAgHBQUDAgAAABIA3gABAAAAAAAAAAEAAAABAAAAAAABAA0AAQABAAAAAAACAAcADgABAAAAAAADAA0AFQABAAAAAAAEAA0AIgABAAAAAAAFAAsALwABAAAAAAAGAA0AOgABAAAAAAAKACwARwABAAAAAAALABIAcwADAAEECQAAAAIAhQADAAEECQABABoAhwADAAEECQACAA4AoQADAAEECQADABoArwADAAEECQAEABoAyQADAAEECQAFABYA4wADAAEECQAGABoA+QADAAEECQAKAFgBEwADAAEECQALACQBayBlLWljb25zLW1ldHJvUmVndWxhcmUtaWNvbnMtbWV0cm9lLWljb25zLW1ldHJvVmVyc2lvbiAxLjBlLWljb25zLW1ldHJvRm9udCBnZW5lcmF0ZWQgdXNpbmcgU3luY2Z1c2lvbiBNZXRybyBTdHVkaW93d3cuc3luY2Z1c2lvbi5jb20AIABlAC0AaQBjAG8AbgBzAC0AbQBlAHQAcgBvAFIAZQBnAHUAbABhAHIAZQAtAGkAYwBvAG4AcwAtAG0AZQB0AHIAbwBlAC0AaQBjAG8AbgBzAC0AbQBlAHQAcgBvAFYAZQByAHMAaQBvAG4AIAAxAC4AMABlAC0AaQBjAG8AbgBzAC0AbQBlAHQAcgBvAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAHUAcwBpAG4AZwAgAFMAeQBuAGMAZgB1AHMAaQBvAG4AIABNAGUAdAByAG8AIABTAHQAdQBkAGkAbwB3AHcAdwAuAHMAeQBuAGMAZgB1AHMAaQBvAG4ALgBjAG8AbQAAAAACAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwBAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0AB2hvbWUtMDELQ2xvc2UtaWNvbnMHbWVudS0wMQR1c2VyB0JUX2luZm8PU2V0dGluZ19BbmRyb2lkDWNoZXZyb24tcmlnaHQMY2hldnJvbi1sZWZ0CE1UX0NsZWFyDE1UX0p1bmttYWlscwRzdG9wAAA=) format('truetype');
        font-weight: normal;
        font-style: normal;
    }

    .handler.burg-icon:before {
        content: '\e10d';
        font-size: 16px;
    }

    .handler.burg-icon {
        float: right;
        padding-top: 2%;
    }
</style>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication.Controllers
{
    public class HomeController : Controller
    {
        public class spacingModel
        {
            public double[] cellSpacing { get; set; }
        }
        public class ChartData
        {
            public string month;
            public double sales;
        }
        public class LineData
        {
            public double x;
            public double y;
        }

        public class PieData
        {
            public string x;
            public double y;
            public string text;
        }
        public ActionResult Index()
        {
            List<ChartData> chartData = new List<ChartData>
            {
                new ChartData {
                    month = "Jan",
                    sales = 35,
                },
                new ChartData {
                    month = "Feb",
                    sales = 28,
                },
                new ChartData {
                    month = "Mar",
                    sales = 34,
                },
                 new ChartData {
                    month = "Apr",
                    sales = 32,
                },
                new ChartData {
                    month = "May",
                    sales = 40,
                },
                new ChartData {
                    month = "Jun",
                    sales = 32,
                },
                new ChartData {
                    month = "Jul",
                    sales = 35,
                },
                new ChartData {
                    month = "Aug",
                    sales = 55,
                },
                new ChartData {
                    month = "Sep",
                    sales = 38,
                },
                 new ChartData {
                    month = "Oct",
                    sales = 30,
                },
                new ChartData {
                    month = "Nov",
                    sales = 25,
                },
                new ChartData {
                    month = "Dec",
                    sales = 32,
                }
            };
            ViewBag.chartSource = chartData;

            List<LineData> lineData = new List<LineData>
            {
                new LineData {
                    x = 2013,
                    y = 28,
                },
                new LineData {
                    x = 2014,
                    y = 25,
                },
                new LineData {
                    x = 2015,
                    y = 26,
                },
                new LineData {
                    x = 2016,
                    y = 27,
                },
                new LineData {
                    x = 2017,
                    y = 32,
                },
                new LineData {
                    x = 2018,
                    y = 35,
                }
            };
            ViewBag.lineSource = lineData;

            List<PieData> pieData1 = new List<PieData>
            {
                new PieData {
                    x = "Chrome",
                    y = 37,
                    text = "37%",
                },
                new PieData {
                    x = "UC Browser",
                    y = 17,
                    text = "17%",
                },
                new PieData {
                    x = "iPhone",
                    y = 19,
                    text = "19%",
                },
                new PieData {
                    x = "Others",
                    y = 4,
                    text = "4%",
                },
                new PieData {
                    x = "Opera",
                    y = 11,
                    text = "11%",
                },
                new PieData {
                    x = "Android",
                    y = 12,
                    text = "12%",
                }
            };
            ViewBag.pieSource1 = pieData1;

            spacingModel modelValue = new spacingModel();
            modelValue.cellSpacing = new double[] { 10, 10 };
            return View(modelValue);
        }
    }
}

Customizing the dragging handler

Disable dragging of panels

19 Dec 202224 minutes to read

By default, the dragging of panels is enabled in Dashboard Layout. It can also be disabled with the help of allowDragging API. Setting allowDragging to false disables the dragging functionality in Dashboard Layout.

@model WebApplication.Controllers.HomeController.spacingModel

<div>
    <ejs-dashboardlayout id="dashboard_layout" columns="5" cellSpacing="@Model.cellSpacing" allowDragging="false">
        <e-dashboardlayout-panels>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="0" col="0" content="<div>0</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="3" sizeY="2" row="0" col="1" content="<div>1</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="3" row="0" col="4" content="<div>2</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="1" col="0" content="<div>3</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="2" sizeY="1" row="2" col="0" content="<div>4</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="2" col="2" content="<div>5</div>">
            </e-dashboardlayout-panel>
            <e-dashboardlayout-panel sizeX="1" sizeY="1" row="2" col="3" content="<div>6</div>">
            </e-dashboardlayout-panel>
        </e-dashboardlayout-panels>
    </ejs-dashboardlayout>
</div>

<style>
    #dashboard_layout .e-panel .e-panel-container {
        vertical-align: middle;
        font-weight: 600;
        font-size: 20px;
        text-align: center;
        line-height: 90px;
    }
</style>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication.Controllers
{
    public class HomeController : Controller
    {
        public class spacingModel
        {
            public double[] cellSpacing { get; set; }
        }
        public ActionResult Index()
        {
            spacingModel modelValue = new spacingModel();
            modelValue.cellSpacing = new double[] { 10, 10 };
            return View(modelValue);
        }
    }
}

Disable dragging

NOTE

You can refer to our ASP.NET Core Dashboard Layout feature tour page for its groundbreaking feature representations. You can also explore our ASP.NET Core Dashboard Layout example to know how to present and manipulate data.