jQuery UI Widgets › Forums › Plugins › Validator, Drag & Drop, Sortable › Disabling/enabling jqxDragDrop
Tagged: angular grid, Cell, cursor, disable, drag, drag cell, drag row, drop, grid, jquery grid, jqxdragdrop, jqxgrid, move
This topic contains 9 replies, has 2 voices, and was last updated by Dimitar 9 years, 3 months ago.
-
Author
-
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.
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,
DimitarjQWidgets team
http://www.jqwidgets.com/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,
–jcHi jc,
Please try calling this when disabling the drag and drop functionality:
$(document).css('cursor', 'default');
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Update: Actually, the code should be:
$('body').css('cursor', 'default');
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/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.
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>
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,
DimitarjQWidgets team
http://www.jqwidgets.com/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.
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,
DimitarjQWidgets team
http://www.jqwidgets.com/ -
AuthorPosts
You must be logged in to reply to this topic.