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

Copying ListBox Drag and Drop

4 Answers 481 Views
ListBox
This is a migrated thread and some comments may be shown as answers.
Nikolay
Top achievements
Rank 1
Nikolay asked on 16 Feb 2019, 03:01 AM

Hello!

Would you please give me an idea where to start to solve the following problem:

I need two list boxes, lets' call them palette and list. 

I need to perform following actions via drag and drop:

1) COPY items from 'palette' to 'list' (e.g. item remains in 'palette' and appears in 'list'),

2) reorder items in 'list'

3) REMOVE items from 'list' (e.g 'item disappears at 'list' but does not appear at 'palette').

4) I do NOT need reordering in 'palette'. 

A practical example of such task would be... let say you have a restaurant menu and want to build an order dragging menu items into the order.

My guess was that it should be possible via analyzing the current drop target in drop or dragend events, but it seems like all I have there is the drag source and the items dragged.

The source code seems to try to determine the drop target via searching which of two listboxes (source or 'connected') the current placeholder belongs to, however I hesitate  to use this approach as placeholder information seems to be not a part of public API, so, I guess, there is no promise of backward compatibility in future.  

I also found an example you provided few years ago, where similar problem partially solved by simply adding the removed item back to palette, but this looks quite weird, I  would hesitate to use such visual behavior in a real project. 

So,  I would really appreciate a head up at an approach to be used, or to a good example on how this task is supposed to be solved in Kendo UI for JQuery architecture. 

Thank you very much for your time!

4 Answers, 1 is accepted

Sort by
0
Nikolay
Top achievements
Rank 1
answered on 18 Feb 2019, 04:58 PM

Below is an example of the JavaScript that initializes two listboxes - menu and order where items can be dragged from menu to order, but menu cannot be reordered and items are not deleted from menu. However, I highlighted in comments all items what relies on the source code of Kendo UI which is not included into the official documentation, so, from my point of view, aren't reliable. What I am looking for is to avoid such dependencies if it is possible. 

 

//two listboxes
//menu - items can be dragged to the order but remains in the menu
var menu;
var order;
 
//identify what the current drop target it
function whereIsPanelPlaceholder() {
    //using of menu.placeholder relies on non-documented behavior!!!
    if (menu == undefined || menu.placeholder == undefined) {
        return undefined;
    }
 
    if (menu.items().index(menu.placeholder) >= 0) {
        return menu;
    }
 
    if (order == undefined) {
        return undefined;
    }
 
    if (order.items().index(menu.placeholder) >= 0) {
        return order;
    }
    return undefined;
}
 
$(document).ready(function () {
    $('#menu').kendoListBox({
        dataValueField: 'value',
        dataTextField: 'text',
        dataSource: [
            { value: 'item5', text: 'Item Five' }, { value: 'item4', text: 'Item Four' },
            { value: 'item1', text: 'Item One' }, { value: 'item2', text: 'Item Two' },
            { value: 'item5', text: 'Item Five' }, { value: 'item2', text: 'Item Two' },
            { value: 'item6', text: 'Item Six' }
        ],
        draggable: {
            enabled: true,
            hint: function (el) {
                //creating hint relies on non-documented behavior!!!
                var hint = el.clone().removeClass('k-ghost').removeClass('k-state-focused')
                    .addClass('k-state-selected k-reset k-drag-clue k-state-disabled').width(el.width());
                menu.my_hint = hint;
                return hint;
            }
        },
        drag: function(e) {
            if (whereIsPanelPlaceholder() == order) {
                if (menu.my_hint.is('.k-state-disabled')) {
                    menu.my_hint.removeClass('k-state-disabled');
                }
            } else {
                if (!menu.my_hint.is('.k-state-disabled')) {
                    menu.my_hint.addClass('k-state-disabled');
                }
            }
        },
        drop: function (e) {
            //custom drop function relies on non-documented behavior!!!
            e.preventDefault();
            if (whereIsPanelPlaceholder() == order) {
                order._addItemAt(menu.dataItem(menu.draggedElement), order.items().index(menu.placeholder));
            }
        }
    });
    menu = $('#menu').data('kendoListBox');
    taghelpers_listbox_setValueJs('menu',
        'content',
        [
            { value: 'item1', text: 'Item One' }, { value: 'item2', text: 'Item Two' },
            { value: 'item3', text: 'Item Three' }, { value: 'item4', text: 'Item Four' },
            { value: 'item5', text: 'Item Five' }, { value: 'item6', text: 'Item Six' }
        ]);
 
    $('#order').kendoListBox({
        dataValueField: 'value',
        dataTextField: 'text',
        draggable: { enabled: true },
        dropSources: ['menu', 'order'],
        toolbar: { position: 'right', tools: ['moveUp', 'moveDown', 'remove'] }
    });
    order = $('#order').data('kendoListBox');
0
Nikolay
Top achievements
Rank 1
answered on 18 Feb 2019, 05:13 PM

And I hope did everything right preparing sample in Dojo, it should be here :-)

https://dojo.telerik.com/iPEFALAh/2

0
Nikolay
Top achievements
Rank 1
answered on 18 Feb 2019, 05:14 PM
And I hope I did everything right to share this code in Dojo :-)

Code in Dojo
0
Tsvetomir
Telerik team
answered on 19 Feb 2019, 01:53 PM
Hi Nikolay,

Thank you for the provided information, and the final product as well.

The hint and the placeholder properties are used internally and they are part of the draggable object. The initialization of the ListBox uses the draggable, hence the ListBox has the same configuration settings as the draggable. Information on the placeholder and hint options is available in the Kendo.ui.Draggable API documentation.

More information on both of them can be found here:

 As per the private method that is used ("_addItemAt"), it is used internally and it is executed at a data source level. If you would like to use the API of the DataSource to achieve the same result, make use of the insert() method as follows:


order.dataSource.insert(order.items().index(menu.placeholder), menu.dataItem(menu.draggedElement));

You can find the updated Dojo sample at:

https://dojo.telerik.com/ElAJipoj

Let me know in case additional questions arise.


Kind regards,
Tsvetomir
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
ListBox
Asked by
Nikolay
Top achievements
Rank 1
Answers by
Nikolay
Top achievements
Rank 1
Tsvetomir
Telerik team
Share this question
or