jQuery UI Widgets Forums Plugins Validator, Drag & Drop, Sortable Disabling/enabling jqxDragDrop

This topic contains 9 replies, has 2 voices, and was last updated by  Dimitar 8 years, 7 months ago.

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
  • Disabling/enabling jqxDragDrop #74548

    jcwren
    Participant

    I have a grid that I have drag’n-drop configured on. I’d like to be able to enable/disable the drag’n-drop programmatically. It appears that the ‘disable’ and ‘cursor’ parameters can be specified when jqxDragDrop is initialized, but subsequent calls do not honor the ‘disable’ and ‘cursor’ parameters.

    In particular, my grid supports a context menu. Right-clicking brings up the context menu, but the mouse is moved out of the context menu, the drag’n-drop functionality is still active. I want to disable drag’n-drop and change the cursor to from ‘move’ to ‘arrow’ while the context menu is open, regardless of where the mouse cursor is on the page.

    To disable jqxDragDrop and change the cursor, I’m using the same basic technique as when it’s created (which comes from the ‘Drag to a Form’ demo code):

    var gridCells = $('#grid').find ('.jqx-grid-cell');
    gridCells.jqxDragDrop ({disabled: true, cursor: 'arrow'});

    Displaying the values in ‘gridCells’ shows it has the correct cells in the grid selected. And even after the context menu is dismissed, the drag’n-drop is still enabled, and the cursor is still the ‘move’ icon.

    In the grid’s ‘rendered’ function, where the jqxDragDrop is initialized, if I disable it there, or change the cursor, that does take effect. It’s just the subsequent calls don’t.

    Disabling/enabling jqxDragDrop #74591

    Dimitar
    Participant

    Hello jcwren,

    Please take a look at the following example (based on the demo Drag to a Form). We hope it is helpful to you:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
        <script type="text/javascript" src="../../scripts/jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.sort.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.filter.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.grouping.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.columnsresize.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.edit.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.columnsreorder.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.pager.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxexpander.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdragdrop.js"></script>
        <script type="text/javascript" src="../../scripts/demos.js"></script>
        <script type="text/javascript" src="generatedata.js"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                var source =
                {
                    localdata: generatedata(10),
                    datafields:
                    [
                        { name: 'firstname', type: 'string' },
                        { name: 'lastname', type: 'string' },
                        { name: 'productname', type: 'string' }
                    ],
                    datatype: "array"
                };
    
                var dataAdapter = new $.jqx.dataAdapter(source);
                var columns = [
                      { text: 'First Name', dataField: 'firstname', width: 100 },
                      { text: 'Last Name', dataField: 'lastname', width: 100 },
                      { text: 'Product', dataField: 'productname' }
                    ];
    
                $("#grid").on('rowclick', function () {
                    // put the focus back to the Grid. Otherwise, the focus goes to the drag feedback element.
                    $("#grid").jqxGrid('focus');
                });
    
                var dragDropEnabled = true;
    
                // create data grids.
                $("#grid").jqxGrid(
                {
                    width: 600,
                    source: dataAdapter,
                    autoheight: true,
                    pageable: true,
                    sortable: true,
                    columns: columns,
                    rendered: function () {
                        if (dragDropEnabled === true) {
                            // select all grid cells.
                            var gridCells = $('#grid').find('.jqx-grid-cell');
                            if ($('#grid').jqxGrid('groups').length > 0) {
                                gridCells = $('#grid').find('.jqx-grid-group-cell');
                            }
    
                            // initialize the jqxDragDrop plug-in. Set its drop target to the second Grid.
                            gridCells.jqxDragDrop({
                                appendTo: 'body', dragZIndex: 99999,
                                dropAction: 'none',
                                initFeedback: function (feedback) {
                                    feedback.height(70);
                                    feedback.width(220);
                                }
                            });
    
                            // initialize the dragged object.
                            gridCells.off('dragStart');
                            gridCells.on('dragStart', function (event) {
                                var value = $(this).text();
                                var position = $.jqx.position(event.args);
                                var cell = $("#grid").jqxGrid('getcellatposition', position.left, position.top);
                                $(this).jqxDragDrop('data', $("#grid").jqxGrid('getrowdata', cell.row));
                                var groupslength = $('#grid').jqxGrid('groups').length;
                                // update feedback's display value.
                                var feedback = $(this).jqxDragDrop('feedback');
                                var feedbackContent = $(this).parent().clone();
                                var table = '<table>';
                                $.each(feedbackContent.children(), function (index) {
                                    if (index < groupslength)
                                        return true;
    
                                    table += '<tr>';
                                    table += '<td>';
                                    table += columns[index - groupslength].text + ': ';
                                    table += '</td>';
                                    table += '<td>';
                                    table += $(this).text();
                                    table += '</td>';
                                    table += '</tr>';
                                });
    
                                table += '</table>';
                                feedback.html(table);
                            });
                            gridCells.off('dragEnd');
                            gridCells.on('dragEnd', function (event) {
                                var value = $(this).jqxDragDrop('data');
                                var position = $.jqx.position(event.args);
                                var pageX = position.left;
                                var pageY = position.top;
                                var $form = $("#form");
    
                                var targetX = $form.offset().left;
                                var targetY = $form.offset().top;
                                var width = $form.width();
                                var height = $form.height();
    
                                // fill the form if the user dropped the dragged item over it.
                                if (pageX >= targetX && pageX <= targetX + width) {
                                    if (pageY >= targetY && pageY <= targetY + height) {
                                        $("#firstName").val(value.firstname);
                                        $("#lastName").val(value.lastname);
                                        $("#product").val(value.productname);
                                    }
                                }
                            });
                        }
                    }
                });
    
                $("#form").jqxExpander({ width: 250, toggleMode: 'none', showArrow: false });
    
                $('#disableDragDrop, #enableDragDrop').jqxButton();
    
                $('#disableDragDrop').click(function () {
                    dragDropEnabled = false;
                    $("#grid").jqxGrid('render');
                });
    
                $('#enableDragDrop').click(function () {
                    dragDropEnabled = true;
                    $("#grid").jqxGrid('render');
                });
            });
        </script>
    </head>
    <body class='default'>
        <div id='jqxWidget'>
            <div style="float: left;" id="grid">
            </div>
            <div style="margin-left: 20px; float: left;" id="form">
                <div>
                    Form Panel
                </div>
                <div>
                    <form>
                    <table>
                        <tr>
                            <td>
                                First Name:
                            </td>
                            <td>
                                <input id="firstName" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                Last Name:
                            </td>
                            <td>
                                <input id="lastName" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                Product:
                            </td>
                            <td>
                                <input id="product" />
                            </td>
                        </tr>
                    </table>
                    </form>
                </div>
            </div>
        </div>
        <div style="clear: both;">
            <button id="disableDragDrop" style="margin-top: 25px;">
                Disable cell drag and drop</button>
            <button id="enableDragDrop">
                Enable cell drag and drop</button>
        </div>
    </body>
    </html>

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Disabling/enabling jqxDragDrop #74626

    jcwren
    Participant

    Dimitar,

    Thanks. That comes *very* close, there’s still one behavior I’d like to eliminate, if possible. In the grid’s ‘cellclick’ handler, I set dragDropEnabled=false, and call the grid’s render function, then open the context menu. The context menu opens, but the cursor remains the ‘move’ cursor until the next movement of the mouse. As soon as the mouse is moved at all, the cursor reverts to the arrow.

    Would you have a suggestion to get the cursor to change immediately, without requiring any mouse movement?

    Thank you,
    –jc

    Disabling/enabling jqxDragDrop #74654

    Dimitar
    Participant

    Hi jc,

    Please try calling this when disabling the drag and drop functionality:

    $(document).css('cursor', 'default');

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Disabling/enabling jqxDragDrop #74658

    Dimitar
    Participant

    Update: Actually, the code should be:

    $('body').css('cursor', 'default');

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Disabling/enabling jqxDragDrop #74677

    jcwren
    Participant

    Excellent. It works, but for it to work correctly, I had to do it like this:

    if (dragDropEnabled === true) {
      ...
    } else
      $('body').css('cursor', 'default');

    Doing it immediately after the $('#grid').jqxGrid ('render') call caused the cursor to change to the default, but as soon as the mouse was back over the grid, it reverted to the ‘move’ cursor. Moving it into the rendered function gets it all working correctly.

    Thank you.

    Disabling/enabling jqxDragDrop #77235

    jcwren
    Participant

    Dimitar,

    With jqWidgets 3.9.0, there appears to be an issue that’s cropped up with re-rendering the grid inside the ‘closed’ event for jqxMenu. In the code below, when the $("#grid").jqxGrid ('render'); is called, I get the following error:

    Uncaught TypeError: Cannot read property 'length' of undefined

    If I put a 10 millisecond setTimeout() call to delay calling the render function, it works. However, that feels like a horrible kludge. Is there some better way to handle re-rendering the grid when the context menu is closed? If I don’t re-render the grid, then the drag-drop functionality doesn’t work afterwards.

    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
        <script type="text/javascript" src="../../scripts/jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.sort.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.filter.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.grouping.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.columnsresize.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.edit.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.columnsreorder.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.pager.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxexpander.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdragdrop.js"></script>
        <script type="text/javascript" src="../../scripts/demos.js"></script>
        <script type="text/javascript" src="generatedata.js"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                var source =
                {
                    localdata: generatedata(10),
                    datafields:
                    [
                        { name: 'firstname', type: 'string' },
                        { name: 'lastname', type: 'string' },
                        { name: 'productname', type: 'string' }
                    ],
                    datatype: "array"
                };
    
                var dataAdapter = new $.jqx.dataAdapter(source);
                var columns = [
                      { text: 'First Name', dataField: 'firstname', width: 100 },
                      { text: 'Last Name', dataField: 'lastname', width: 100 },
                      { text: 'Product', dataField: 'productname' }
                    ];
    
                $("#grid").on('rowclick', function () {
                    // put the focus back to the Grid. Otherwise, the focus goes to the drag feedback element.
                    $("#grid").jqxGrid('focus');
                });
    
                var dragDropEnabled = true;
    
                $('#contextMenu').jqxMenu ({
                  width: 100,
                  height: null,
                  autoOpenPopup: false,
                  mode: 'popup'
                });
    
                $('#contextMenu').on ('closed', function () {
                  $('#grid').jqxGrid ('render');
                });
    
                $('#grid').on ('contextmenu', function () {
                  return false;
                });
                // create data grids.
                $("#grid").jqxGrid(
                {
                    width: 600,
                    source: dataAdapter,
                    autoheight: true,
                    pageable: true,
                    sortable: true,
                    columns: columns,
                    rendered: function () {
                        if (dragDropEnabled === true) {
                            // select all grid cells.
                            var gridCells = $('#grid').find('.jqx-grid-cell');
                            if ($('#grid').jqxGrid('groups').length > 0) {
                                gridCells = $('#grid').find('.jqx-grid-group-cell');
                            }
    
                            // initialize the jqxDragDrop plug-in. Set its drop target to the second Grid.
                            gridCells.jqxDragDrop({
                                appendTo: 'body', dragZIndex: 99999,
                                dropAction: 'none',
                                initFeedback: function (feedback) {
                                    feedback.height(70);
                                    feedback.width(220);
                                }
                            });
    
                            // initialize the dragged object.
                            gridCells.off('dragStart');
                            gridCells.on('dragStart', function (event) {
                                var value = $(this).text();
                                var position = $.jqx.position(event.args);
                                var cell = $("#grid").jqxGrid('getcellatposition', position.left, position.top);
                                $(this).jqxDragDrop('data', $("#grid").jqxGrid('getrowdata', cell.row));
                                var groupslength = $('#grid').jqxGrid('groups').length;
                                // update feedback's display value.
                                var feedback = $(this).jqxDragDrop('feedback');
                                var feedbackContent = $(this).parent().clone();
                                var table = '<table>';
                                $.each(feedbackContent.children(), function (index) {
                                    if (index < groupslength)
                                        return true;
    
                                    table += '<tr>';
                                    table += '<td>';
                                    table += columns[index - groupslength].text + ': ';
                                    table += '</td>';
                                    table += '<td>';
                                    table += $(this).text();
                                    table += '</td>';
                                    table += '</tr>';
                                });
    
                                table += '</table>';
                                feedback.html(table);
                            });
                            gridCells.off('dragEnd');
                            gridCells.on('dragEnd', function (event) {
                                var value = $(this).jqxDragDrop('data');
                                var position = $.jqx.position(event.args);
                                var pageX = position.left;
                                var pageY = position.top;
                                var $form = $("#form");
    
                                var targetX = $form.offset().left;
                                var targetY = $form.offset().top;
                                var width = $form.width();
                                var height = $form.height();
    
                                // fill the form if the user dropped the dragged item over it.
                                if (pageX >= targetX && pageX <= targetX + width) {
                                    if (pageY >= targetY && pageY <= targetY + height) {
                                        $("#firstName").val(value.firstname);
                                        $("#lastName").val(value.lastname);
                                        $("#product").val(value.productname);
                                    }
                                }
                            });
                        }
                    }
                });
    
                $('#grid').on ('cellclick', function (event) {
                  if (event.args.rightclick) {
                    var rowindex = event.args.rowindex;
                    $('#grid').jqxGrid ('render');
                    $('#grid').jqxGrid ('selectrow', rowindex);
                    var scrollTop = $(window).scrollTop ();
                    var scrollLeft = $(window).scrollLeft ();
                    $('#contextMenu').jqxMenu ('open', parseInt (event.args.originalEvent.clientX) + 5 + scrollLeft, parseInt (event.args.originalEvent.clientY) + 5 + scrollTop);
                    return false;
                  }
                });
    
                $("#form").jqxExpander({ width: 250, toggleMode: 'none', showArrow: false });
    
                $('#disableDragDrop, #enableDragDrop').jqxButton();
    
                $('#disableDragDrop').click(function () {
                    dragDropEnabled = false;
                    $("#grid").jqxGrid('render');
                });
    
                $('#enableDragDrop').click(function () {
                    dragDropEnabled = true;
                    $("#grid").jqxGrid('render');
                });
            });
        </script>
    </head>
    <body class='default'>
        <div id='jqxWidget'>
            <div style="float: left;" id="grid">
            </div>
            <div style="margin-left: 20px; float: left;" id="form">
                <div>
                    Form Panel
                </div>
                <div>
                    <form>
                    <table>
                        <tr>
                            <td>
                                First Name:
                            </td>
                            <td>
                                <input id="firstName" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                Last Name:
                            </td>
                            <td>
                                <input id="lastName" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                Product:
                            </td>
                            <td>
                                <input id="product" />
                            </td>
                        </tr>
                    </table>
                    </form>
                </div>
            </div>
        </div>
        <div style="clear: both;">
            <button id="disableDragDrop" style="margin-top: 25px;">
                Disable cell drag and drop</button>
            <button id="enableDragDrop">
                Enable cell drag and drop</button>
        </div>
        <div style="display: none;" id="contextMenu">
          <ul>
            <li id="contextEdit">Edit This</li>
            <li id="contextAdd"> Add New</li>
            <li id="contextDelete">Delete This</li>
          </ul>
        </div>
    </body>
    </html>
    
    Disabling/enabling jqxDragDrop #77247

    Dimitar
    Participant

    Hello jcwren,

    I am not sure why this issue occurs, but, testing your example, even if the closed event handler is removed entirely (along with the call to render, the drag and drop functionality works fine after the menu is closed.

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

    Disabling/enabling jqxDragDrop #77265

    jcwren
    Participant

    The sample code above was intended to demonstrate the error message that occurs when re-rendering the grid from inside the context menu close event.

    In my actual code it’s necessary to re-render the grid to get drag-n’drop to work after programmatically disabling it, per post #1. The suggestions you provided in your two replies resolved the issue of disabling drag’n-drop while the context menu is open.

    The error that appears now is a results of some change between 3.8.2 and 3.9.0. The setTimeout call to delay re-rendering the grid does not feel like a proper solution. I was hoping you might have an idea of a better way to either re-enable the drag’n-drop functionality or re-render the grid.

    Disabling/enabling jqxDragDrop #77302

    Dimitar
    Participant

    Hi jcwren,

    We will look into this issue, but, unfortunately, this is all we can offer you on the matter at the moment.

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

Viewing 10 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic.