This is a migrated thread and some comments may be shown as answers.

KendoUI drag and drop rearranging + drag and drop between grids.

6 Answers 455 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Samuel
Top achievements
Rank 1
Samuel asked on 19 Nov 2012, 10:14 PM
The scenario in the link below is almost exactly what my project requires.

http://demos.telerik.com/aspnet-ajax/grid/examples/programming/draganddrop/defaultcs.aspx

Unfortunately it has taken the better part of 2 weeks hunting through KendoUI's terrible documentation and poorly maintained forums and have not been able to recreate the situation.

Can someone please direct me as to where to find out how to create a set of drag and drop grids?

6 Answers, 1 is accepted

Sort by
0
Rachael
Top achievements
Rank 1
answered on 23 May 2013, 05:39 PM
I saw your other post and my original reply to that one only dealt with sorting within a single grid. I've figured out how to do the sorting within each grid and across two different grids in both directions. In all cases, you need the JQuery UI plugin - it's not an out-of-the-box Kendo function. I've included all my code so you can see how I've set it up. Hopefully this will help you or someone else in the future. Documentation on this stuff is abysmal!

<div style="width: 75%; display: inline-block; float: left;">
 
    <h2>Just Posted</h2>   
    @(Html.Kendo().Grid(Model.JustPosted)
        .Name("justposted-grid")
        .Columns(columns =>
        {
            columns.Bound(e => e.Name)
                .Title("highlighted documents on the home page");
            columns.Bound(e => e.PostingDate)
                .Title("posting date")
                .HeaderHtmlAttributes(new { @class = "dateColumn" });
            columns.Bound(e => e.Id)
                .Title("")
                .HeaderHtmlAttributes(new { @class = "iconColumn" });
        })
        .ClientRowTemplate(
            "<tr class='#: CssClass#' data-id='#: Id#' data-index='#: Index#'>" +
                "<td>#= Name#</td>" +
                "<td class='dateColumn'>#= kendo.toString(PostingDate, 'MM/dd/yyyy')#</td>" +
                "<td class='iconColumn'><a href='/Admin/RecentPostings/View/#: Id#'><img src='/images/admin/_view.gif' /></a></td>" +
             "</tr>"     
        )
        .TableHtmlAttributes(new { @id = "justposted-table", @class = "sortable" })
        .Sortable()
        .Scrollable(scrolling => scrolling.Enabled(false))
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("GetJustPosted", "RecentPostings", new { area = "Admin" }))
         )
    )
 
    <h2>Recent Documents</h2>
    @(Html.Kendo().Grid(Model.RecentDocuments)
        .Name("recentdocs-grid")
        .Columns(columns =>
        {
            columns.Bound(e => e.Name)
                .Title("documents 'approved' in the last 28 days");
            columns.Bound(e => e.PostingDate)
                .Title("posting date")
                .HeaderHtmlAttributes(new { @class = "dateColumn" });
            columns.Template(e => e.Id)
                .Title("")
                .HeaderHtmlAttributes(new { @class = "iconColumn" });
        })
        .ClientRowTemplate(
            "<tr class='#: CssClass#' data-id='#: Id#' data-index='#: Index#'>" +
                "<td>#= Name#</td>" +
                "<td class='dateColumn'>#= kendo.toString(PostingDate, 'MM/dd/yyyy')#</td>" +
                "<td class='iconColumn'><a href='/Admin/RecentPostings/View/#: Id#'><img src='/images/admin/_view.gif' /></a></td>" +
             "</tr>"
        )
        .TableHtmlAttributes(new { @id = "recentdocs-table", @class = "sortable" })
        .Sortable(sorting => sorting.Enabled(true))
        .Scrollable(scrolling => scrolling.Enabled(false))
        .Pageable(paging => paging.Enabled(true))
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("GetRecentDocuments", "RecentPostings", new { area = "Admin" }))
            .PageSize(10)
         )
    )
 
 
</div>
 
<div class="help" style="width: 20%; float: right;">
    <h2>Help</h2>
    <ul>
        <li>To select an item to appear in the Just Posted section on the home page, drag that item from the "Recent Documents" list to the "Just Posted" list and drop it in the appropriate position.</li>
        <li>To remove an item from the Just Posted section on the home page, drag that item from the "Just Posted" list and drop it anywhere in the "Recent Documents" list.</li>
        <li>You may drag and drop items in the "Just Posted" list to reorder them.</li>
    </ul>
</div>
     
<div class="clear"></div>

The corresponding Javascript is here:
<script type="text/javascript">
    $(function () {
        configureSortableRows();
 
        $("#justposted-table,#recentdocs-table").sortable({
            items: 'tr',
            connectWith: '.sortable',
            helper: fixHelperModified,
        }).disableSelection();
 
 
        // This function handles when an item is moved from the recent docs table to the just posted table
        $("#justposted-table").bind("sortreceive", function (event, ui) {
            var confirmationText = 'Are you sure you want to move ' + $(ui.item).find(">:first-child").text();
            var destinationIndex = $(ui.item).index();
 
            if (destinationIndex == 0) {
                confirmationText = confirmationText + ' first';
            }
            else {
                if (destinationIndex == $("#justposted-table tbody tr").length - 1) {
                    confirmationText = confirmationText + ' last';
                }
                else {
                    confirmationText = confirmationText + ' above ' + $("#justposted-grid tbody tr[data-index='" + (destinationIndex) + "']").find(">:first-child").text();
                }
            }
            confirmationText = confirmationText + ' in Recent Postings?';
 
            if (confirm(confirmationText)) {
                $("#justposted-grid").data("kendoGrid").refresh();
            }
            else {
                $("#recentdocs-table").sortable('cancel');
            }
        });
 
        // This function handles when an item is sorted within the just posted table
        $("#justposted-table").bind("sortupdate", function (event, ui) {
            if ($(ui.item).parent().parent().attr('id') == 'justposted-table' && $(ui.sender).attr('id') != 'recentdocs-table') {
                var confirmationText = 'Are you sure you want to move ' + $(ui.item).find(">:first-child").text();
                var destinationIndex = $(ui.item).index();
 
                if ($(ui.item).data('index') < ($(ui.item).index())) {
                    confirmationText = confirmationText + ' below ';
                }
                else {
                    confirmationText = confirmationText + ' above ';
                }
                var destination = $("#justposted-grid tbody tr[data-index='" + (destinationIndex) + "']");
                confirmationText = confirmationText + $(destination).find(">:first-child").text() + '?';
 
                if (confirm(confirmationText)) {
                    $("#justposted-grid").data("kendoGrid").refresh();
                }
                else {
                    $("#justposted-table").sortable('cancel');
                }
            }
        });
 
        // This function handles when an item is sorted within the recent docs table (nothing happens - this isn't allowed)
        $("#recentdocs-table").bind("sortupdate", function (event, ui) {
            if ($(ui.item).parent().parent().attr('id') == 'recentdocs-table' && $(ui.sender).attr('id') != 'justposted-table') {
                event.preventDefault();
            }
        });
 
        // This function handles when an item is moved from the just posted table to the recent docs table
        $("#recentdocs-table").bind("sortreceive", function (event, ui) {
            if (confirm('Are you sure you want to remove ' + $(ui.item).find(">:first-child").text() + ' from Recent Postings?')) {
                $("#recentdocs-grid").data("kendoGrid").refresh();
            }
            else {
                $("#justposted-table").sortable('cancel');
            }
        });
    });
 
    var fixHelperModified = function (e, tr) {
        var $originals = tr.children();
        var $helper = tr.clone();
        $helper.children().each(function (index) {
            $(this).width($originals.eq(index).width());
        });
        return $helper;
    };
 
    function configureSortableRows() {
        $("tbody tr").hover(function () {
            $(this).css('cursor', 'move');
        });
    }
</script>
Note: in my particular instance, sorting was only allowed in the top table and not the bottom one. You can see in the code were I disabled the sorting.
0
Samuel
Top achievements
Rank 1
answered on 23 May 2013, 08:11 PM
I feel quite bad, I actually solved this ages ago - and quite nicely too but never posted the answer. We ended up getting a UI guy who replaced all of KendoUI's functionality within a week or two.
0
Rachael
Top achievements
Rank 1
answered on 23 May 2013, 08:13 PM
No worries - I needed to solve this problem for myself anyway and I thought I'd post a solution for anyone else who might be looking for an answer. It's definitely doable, but not exactly obvious. Any chance you know if your UI person used JQueryUI Sortable even if they didn't use Kendo for the grid?
0
Samuel
Top achievements
Rank 1
answered on 23 May 2013, 08:17 PM
Our UI guy actually doesn't use JQuery at all. He thinks it's pretty terrible. He uses a slightly less known 'mootools' to deal with everything.
0
Samuel
Top achievements
Rank 1
answered on 23 May 2013, 08:26 PM
Went through svn, got my old code that worked with KendoUI. This is the script for 3 tables: Tables, Fields and FieldsToExport (which was given the internal name charonFormat)
<br>
<script type="text/javascript"><br>
<br>
    $("#fieldGrid").delegate("tbody>tr", "dblclick",<br>
    function () {<br>
        transferField();<br>
    });<br>
<br>
    $("#FieldsToExport").delegate("tbody>tr", "dblclick",<br>
        function () {<br>
            transferCharonFormattedField();<br>
        });<br>
<br>
    $("#incrementalSearch").keyup(function () {<br>
        var newVal = $("#incrementalSearch").val().toUpperCase();<br>
        $("#Tables").data("kendoGrid").dataSource.filter({ field: "TableName", operator: "startswith", value: newVal });<br>
    });<br>
<br>
    function moveCharonRowUp() {<br>
        var charonGrid = $('#FieldsToExport').data("kendoGrid");<br>
        var selectedRow = charonGrid.select();<br>
        var list = charonGrid.dataSource.data();<br>
<br>
        var selectedItem;<br>
        selectedRow.each(function () {<br>
            selectedItem = charonGrid.dataItem($(this));<br>
        });<br>
<br>
        var selectedIndex = list.indexOf(selectedItem);<br>
        <br>
        if (selectedIndex == 0 || selectedItem == undefined) {<br>
            return;<br>
        }<br>
<br>
        switchRows(list, selectedIndex, selectedIndex - 1, selectedItem);<br>
<br>
        $('.charonFormatGrid tbody tr:nth-child(' + selectedIndex + ')').addClass('k-state-selected');<br>
    }<br>
<br>
    function moveCharonRowDown() {<br>
        var charonGrid = $('#FieldsToExport').data("kendoGrid");<br>
        var list = charonGrid.dataSource.data();<br>
        var selectedItem;<br>
        charonGrid.select().each(function () {<br>
            selectedItem = charonGrid.dataItem($(this));<br>
        });//todo remove<br>
<br>
        var selectedIndex = list.indexOf(selectedItem);<br>
<br>
        if (selectedIndex == list.length-1 || selectedItem == undefined) {<br>
            return;<br>
        }<br>
<br>
        var nextRowToHighlight = selectedIndex + 2;<br>
<br>
        switchRows(list, selectedIndex, selectedIndex + 1, selectedItem);<br>
<br>
        $('.charonFormatGrid tbody tr:nth-child(' + nextRowToHighlight + ')').addClass('k-state-selected');<br>
    }<br>
    <br>
    function switchRows(list, sourceRow, destinationRow, selectedItem) {<br>
        list.splice(sourceRow, 1);<br>
        list.splice(destinationRow, 0, selectedItem);<br>
    }<br>
<br>
    function transferAllFields() {<br>
        var fieldGrid = $("#Fields").data("kendoGrid");<br>
        var charonGrid = $("#FieldsToExport").data("kendoGrid");<br>
        var fields = fieldGrid.dataSource.data();<br>
        var charonfields = charonGrid.dataSource.data();<br>
        var emptyList = new Array();<br>
<br>
<br>
        var fullList = new Array();<br>
<br>
        for (var j = 0; j < charonfields.length; j++) {<br>
            fullList.push(charonfields[j]);<br>
        }<br>
        for (var i = 0; i < fields.length; i++) {<br>
            fullList.push(fields[i]);<br>
        }<br>
<br>
        fieldGrid.dataSource.data(emptyList);<br>
        charonGrid.dataSource.data(fullList);<br>
    };<br>
<br>
<br>
    function transferAllCharonFormattedFields() {<br>
        var fieldGrid = $("#Fields").data("kendoGrid");<br>
        var charonGrid = $("#FieldsToExport").data("kendoGrid");<br>
        var fields = fieldGrid.dataSource.data();<br>
        var charonfields = charonGrid.dataSource.data();<br>
        <br>
        if (charonfields.length == 0) {<br>
            return;<br>
        }<br>
        var emptyList = new Array();<br>
        <br>
        var fullList = new Array();<br>
        <br>
        for (var i = 0; i < fields.length; i++) {<br>
            fullList.push(fields[i]);<br>
        }<br>
        for (var j = 0; j < charonfields.length; j++) {<br>
            fullList.push(charonfields[j]);<br>
        }<br>
<br>
        fieldGrid.dataSource.data(fullList);<br>
        charonGrid.dataSource.data(emptyList);<br>
        <br>
        <br>
        fieldGrid.dataSource.sort([{ field: "FieldDefinition.IsAutoGenerated", dir: "desc" }, { field: "FieldDefinition.IsKeyField", dir: "desc" }, { field: "FieldDefinition.FieldName", dir: "asc" }]);<br>
    };<br>
<br>
    function transferCharonFormattedField() {<br>
        var fieldsGrid = $("#Fields").data("kendoGrid");<br>
        var charonExportGrid = $("#FieldsToExport").data("kendoGrid");<br>
<br>
        transferBetweenTables(charonExportGrid, fieldsGrid);<br>
<br>
       var rowPosition =  fieldsGrid.dataSource.sort([{ field: "FieldDefinition.IsAutoGenerated", dir: "desc" }, { field: "FieldDefinition.IsKeyField", dir: "desc" }, { field: "FieldDefinition.FieldName", dir: "asc" }]);<br>
        if (rowPosition != 0) {<br>
            $($('#FieldsToExport tbody tr')[rowPosition]).addClass("k-state-selected");<br>
        }<br>
    }<br>
<br>
    function transferField() {<br>
        var fieldsGrid = $("#Fields").data("kendoGrid");<br>
        var charonExportGrid = $("#FieldsToExport").data("kendoGrid");<br>
<br>
        var rowPosition = transferBetweenTables(fieldsGrid, charonExportGrid);<br>
        if (rowPosition != 0) {<br>
            $($('#Fields tbody tr')[rowPosition]).addClass("k-state-selected");<br>
        }<br>
    }<br>
<br>
    function transferBetweenTables(sourceTable, destinationTable) {<br>
        var toAdd = sourceTable.dataItem(sourceTable.select());<br>
        var toRemove = toAdd;<br>
        var rowPosition = sourceTable.select().prevAll().length;<br>
<br>
<br>
        destinationTable.dataSource.data().splice(0, 0, toAdd);<br>
<br>
<br>
        var index = sourceTable.dataSource.data().indexOf(toRemove);<br>
        sourceTable.dataSource.data().splice(index, 1);<br>
<br>
        return rowPosition;<br>
<br>
    }<br>
<br>
<br>
    function formatCells() {<br>
        $("#Fields tbody tr").each(function() {<br>
            var currentRow = $(this);<br>
            var currentRowItem = $("#Fields").data("kendoGrid").dataItem($(this));<br>
            if (currentRowItem.FieldDefinition.IsAutoGenerated) {<br>
                currentRow.addClass('fieldIsAutoGenerated');<br>
            }<br>
            if (currentRowItem.FieldDefinition.IsKeyField) {<br>
                currentRow.addClass('fieldIsPrimaryKey');<br>
            }<br>
        });<br>
    }<br>
<br>
    function tableSelected() {<br>
        $("#FieldsToExport").data("kendoGrid").dataSource.read();<br>
        $("#Fields").data("kendoGrid").dataSource.read();<br>
    }<br>
<br>
    function retrieveFieldData() {<br>
        var result = $('#Tables').data('kendoGrid').select()[0].textContent;<br>
        return {<br>
            tableName: result<br>
        };<br>
    }<br>
</script>
0
Samuel
Top achievements
Rank 1
answered on 23 May 2013, 08:36 PM
Sorry - an update, I decided against drag and drop. Used Moveall and move single buttons.
Tags
Grid
Asked by
Samuel
Top achievements
Rank 1
Answers by
Rachael
Top achievements
Rank 1
Samuel
Top achievements
Rank 1
Share this question
or