#103552
admin
Keymaster

Hi,

It can be achieved with a combination of Razor and Javascript. On the left side of the page, we will have a list with items which we will be able to drag and drop into the Scheduler. The drag and drop is implemented with Javascript.

Example:

@page "/"
@inject IJSRuntime JSRuntime

@using Smart.Blazor.Demos.Data

<style>
    /* This is the CSS used in the demo */
    html,
    body {
        width: 100%;
        height: 100%;
        margin: 0 auto;
        --smart-scheduler-timeline-cell-min-width: 40px;
        --smart-scheduler-event-border-radius: 4px;
        --smart-scheduler-timeline-nonworking-color: var(--smart-background);
    }

    .layout {
        display: flex;
    }

    .events {
        width: 200px;
        margin-right: 50px;
    }

    .smart-scheduler {
        width: calc(100% - 250px);
        height: 100%;
    }
</style>

<Example Name="Scheduler">
    <div class="layout">
        <div class="events">
            <ul>
                @foreach (var item in Items)
                {
                    <li value="@item" draggable="true">@item</li>
                }
            </ul>
        </div>
        <Scheduler OnReady="Ready" @ref="scheduler" Views="@views" View="SchedulerViewType.Week" DateCurrent="@dateCurrent"></Scheduler>
    </div>
</Example>

@code {
    Scheduler scheduler;
    string[] Items = new string[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };

    private object dateCurrent = DateTime.Today;

    private IEnumerable<SchedulerViewType> views = new List<SchedulerViewType>()
{
        SchedulerViewType.Day,
        SchedulerViewType.Week,
        SchedulerViewType.Month,
        SchedulerViewType.Agenda
    };

    public async void Ready(Scheduler scheduler)
    {
        await JSRuntime.InvokeVoidAsync("dragDrop");
    }
    protected override void OnInitialized()
    {
        base.OnInitialized();
    }
}

and the index file.

<!DOCTYPE html>
<html>
<head lang="en-us">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>Smart Blazor Components Library</title>
    <base href="/" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet" />
    <link href="_content/Smart.Blazor/css/smart.default.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <script type="text/javascript" src="js/smart.blazor.js"></script>
    <script type="text/javascript" src="js/rrule.min.js"></script>
    <script type="text/javascript" src="_content/Smart.Blazor/js/smart.elements.js"></script>
    <script type="text/javascript">
        function dragover_handler(ev) {
            ev.preventDefault();
            ev.dataTransfer.dropEffect = 'move';
        }
        function drop_handler(ev) {
            ev.preventDefault();
            const scheduler = document.querySelector('smart-scheduler');
            // Get the target element's data from the data transfer object
            const data = ev.dataTransfer.getData('text/plain').split(',');
            // gets the date from the drop coordinates.
            const date = scheduler.getDateFromCoordinates(ev.clientX, ev.clientY);
            // gets if we dropped over an all day cell.
            const isAllDay = scheduler.getIsAllDayCellFromCoordinates(ev.clientX, ev.clientY);

            if (!date) {
                return;
            }

            const dateStart = date;
            const dateEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours() + 1, date.getMinutes(), 0)

            // adds a new scheduler event.
            scheduler.createEvent(
                data[0],
                data[1],
                dateStart,
                dateEnd,
                isAllDay
            )

            // finds the dragged item.
            const item = [...document.querySelectorAll('[draggable]')].find((item) => {
                if (item.getAttribute('value') === data[1]) {
                    return true;
                }

                return false;
            });

            // removes the dragged item.
            if (item) {
                item.remove();
            }
        }

        function dragstart_handler(ev) {
            // Add the target element's data to the data transfer object
            ev.dataTransfer.setData('text/plain', ev.target.innerHTML + ',' + ev.target.getAttribute('value'));
            ev.dataTransfer.effectAllowed = 'move';
        }

        // called by the scheduler after it is created. Setups drag & drop.
        function dragDrop() {
            const scheduler = document.querySelector('smart-scheduler');

            scheduler.addEventListener('drop', (event) => {
                drop_handler(event);
            });

            scheduler.addEventListener('dragover', (event) => {
                dragover_handler(event);
            });

            document.querySelectorAll('[draggable]').forEach((item) => {
                item.ondragstart = dragstart_handler;
            });
        }

        window.onload = () => {
            //

        
        }
    
        document.oncontextmenu = () => {
            return false;
        }
        // Single Page Apps for GitHub Pages
        // https://github.com/rafrex/spa-github-pages
        // Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
        // ----------------------------------------------------------------------
        // This script checks to see if a redirect is present in the query string
        // and converts it back into the correct url and adds it to the
        // browser's history using window.history.replaceState(...),
        // which won't cause the browser to attempt to load the new url.
        // When the single page app is loaded further down in this file,
        // the correct url will be waiting in the browser's history for
        // the single page app to route accordingly.
        (function (l) {
            if (l.search) {
                var q = {};
                l.search.slice(1).split('&').forEach(function (v) {
                    var a = v.split('=');
                    q[a[0]] = a.slice(1).join('=').replace(/~and~/g, '&');
                });
                if (q.p !== undefined) {
                    window.history.replaceState(null, null,
                        l.pathname.slice(0, -1) + (q.p || '') +
                        (q.q ? ('?' + q.q) : '') +
                        l.hash
                    );
                }
            }
        }(window.location))
    </script>
</head>

<body>
    <div id="app">
        <div style="position:absolute; top:30vh; width:100%; text-align:center">
            <p><i class="fas fa-spin fa-spinner"></i>Loading...</p>
        </div>
    </div>

    <script src="_framework/blazor.webassembly.js"></script>
</body>

</html>

Best regards,
Peter Stoev

Smart UI Team
https://www.htmlelements.com/