Coder Social home page Coder Social logo

ui-grid-draggable-rows's Introduction

Draggable rows plugin for ui-grid

NPM Bower License

Play with HTML5 drag and drop in angular ui-grid.

Preview

Checkout our codepen collection https://codepen.io/collection/AMpZgd/

Install

Install using npm

npm install ui-grid-draggable-rows

Install using bower

bower install ui-grid-draggable-rows

Add plugin as dependency to your module

angular.module("app", ["ui.grid", "ui.grid.draggable-rows"]);

Usage

To add drag and drop functionality you have to insert ui-grid-draggable-rows directive to your table.

<div ui-grid="gridOptions" class="grid" ui-grid-draggable-rows></div>

Now, you have to add draggable wrapper to your rowTemplate. If you have your own template just replace the inner div.

$scope.gridOptions = {
    rowTemplate: '<div grid="grid" class="ui-grid-draggable-row" draggable="true"><div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader, \'custom\': true }" ui-grid-cell></div></div>'
};

To add action after dropping row register new listener on rowDropped event.

$scope.gridOptions.onRegisterApi = function (gridApi) {
    gridApi.draggableRows.on.rowDropped($scope, function (info, dropTarget) {
        console.log("Dropped", info);
    });
};

To enable using a "handle" for dragging the rows, add the useUiGridDraggableRowsHandle property to your gridOptions and add this class to your handle: ui-grid-draggable-row-handle.

$scope.gridOptions.useUiGridDraggableRowsHandle = true;

Additional styling

When you drag a row over others they get additional css class ui-grid-draggable-row-over. This plugin has default styling for these elements. If you are using less you could import styles into your application.

@import "/path/to/bower_components/ui-grid-draggable-rows/less/draggable-rows";

If you are using clear css just put these styles into your stylesheet.

.ui-grid-draggable-row-target {
  opacity: 0.5 !important;
}
.ui-grid-draggable-row {
  height: 30px;
}
.ui-grid-draggable-row-over {
  position: relative;
}
.ui-grid-draggable-row-over:before {
  content: "";
  display: block;
  position: absolute;
  left: 0;
  width: 100%;
  border-bottom: 1px dotted #AAA;
}
.ui-grid-draggable-row-over--above:before {
  top: 0;
}
.ui-grid-draggable-row-over--below:before {
  bottom: 0;
}

List of events

Event Listener Original event Description
rowDragged function(info, rowElement) onDragStart Fired once during start dragging
rowEnterRow function(info, rowElement) onDragEnter Fired when draggable row enter on other row
rowOverRow function(info, rowElement) onDragOver Fired when draggable row is over other row
rowLeavesRow function(info, rowElement) onDragLeave Fired when draggable row leaves other row
rowFinishDrag function() onDragEnd Fired after finish dragging
beforeRowMove function(from, to, data) Fired before a row's index is changed
rowDropped function(info, targetElement) onDrop Fired when row is dropping to other row

To listen these events just register new listener via ui-grid API.

info is an object with the following properties

{
    draggedRow: domElement,     // The dragged row element

    draggedRowEntity: object,   // The object the dragged row represents in the grid data (`row.entity`)

    targetRow: domElement,      // The target row element

    targetRowEntity: object,    // The object the target row represents in the grid data

    position: string,           // String that indicates whether the row was dropped
                                // above or below the drop target (determined by half row height)
                                // eg. 'above' or 'below'

    fromIndex: int,             // Original position of dragged row in sequence

    toIndex: int,               // New position of dragged row in the sequence
}
$scope.gridData.onRegisterApi = function (gridApi) {
    gridApi.draggableRows.on.rowDragged($scope, function (info, rowElement) {
        console.log("Start dragging...");

        // do something
    });
};

Public methods

Method Description
setDragDisabled(boolean) Enable or disable drag 'n drop functionality

All public methods are accessible through dragndrop object from gridApi. See example below

$scope.gridData.onRegisterApi = function (gridApi) {
    gridApi.dragndrop.setDragDisabled($scope.enabled);
};

Handling grouping

In order to handle grouping you have to manually set the 'from' grouping value to that of the 'to' as shown below.

$scope.gridData.onRegisterApi = function (gridApi) {
    gridApi.draggableRows.on.beforeRowMove($scope, function (from, to, data) {
        console.log("Setting the grouping values");
        data[from].groupValue = data[to].groupValue;
    });
};

Todo

  • automatically insert the required template row
  • write test (better late than never)
  • improve documentation

Support

Project is currently maintained by codewave.eu.

Author

Plugin ui-grid-draggable-rows has been originally developed by Szymon Krajewski.

License

The MIT License © 2015 - 2016

ui-grid-draggable-rows's People

Contributors

akurg avatar andrzejwp avatar bbobrian avatar boroth avatar ccicpgreen avatar dzast avatar homerjam avatar igallagher-conga avatar karolnet avatar martijnwelker avatar michaelsl avatar nickclyde avatar skrajewski avatar waszislaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ui-grid-draggable-rows's Issues

Space instead of border between rows

Hi, I would like to know if there a way to put some "space" or a "row-space" between the rows interested by the drag and drop event.
Now, while I'm dragging, there's only a grey border to highlight the future position of my row but this make it hard to drop, especialy if you work with a browser zoom < 100%.
Could someone please help me with this?

ex

How do drag handles work?

To enable using a "handle" for dragging the rows, add the useUiGridDraggableRowsHandle property to your gridOptions and add this class to your handle: ui-grid-draggable-row-handle.

Can you offer some sample code or documentation that shows how the ui-grid-draggable-row-handle class is used in HTML and defined in CSS?

Moving row two up doesn't reorder

the only way around this seems to be to move row 1 down to swap their positions.
Changing the 'move' function to this fixes it
var move = function (from, to) {
/*jshint validthis: true */
if (from === 1 && to === 1) {
from = 0;
}
this.splice(to, 0, this.splice(from, 1)[0]);
};

Memory leak

This plugin doesn't clean up its event listeners added via addEventListener, so memory leaks occur when using it.

I've created a pull to fix this: #65

Can we get this merged?

Numerous problems with draggable rows in combination with grouping

There are numerous problems in combination with grouping.
When you drag a row between two group headers you expect the row to be inserted at the correct position.
For example: if you drags a row below a group header, the dragged row needs to be inserted at the target group header. If you drags a row above a group header, the dragged row needs to be inserted at the group header above the target.

I created a codepen to show the problem.
codepen

I also created a PR (which is probably not fully covered, but the main problem is covered)
pull request

Thanks for looking into this.

Drop not working when two grids and the second is empty

Hey, I've been working on the drag and drop for a while, but now I'm facing a problem that's when dropping a grid row into another grid which is empty, the ability to drop it never fire, if someone can help me please :(

ui-grid-draggable-rows breaks css styles for ui-grid-selection

css rule to mark selected rows when using ui-grid-selection feature (from ui-grid.css)

.ui-grid-row.ui-grid-row-selected > [ui-grid-row] > .ui-grid-cell {
  background-color: #c9dde1;
}

does not work with a rowTemplate (as suggested in documentation)

rowTemplate:
  '<div grid="grid" class="ui-grid-draggable-row" draggable="true">' +
  $templateCache.get('ui-grid/ui-grid-row') +
  '</div>',

because of the additional

quick fix to css rule:

.ui-grid-row.ui-grid-row-selected > [ui-grid-row] .ui-grid-cell {
  background-color: #c9dde1;
}

(notice removal of the second ">")

Is it possible for me to make the drop conditional?

I am implementing a reorder of the ui-grid using draggable interface. Is it possible to make the drop conditional? As in if drop is to area x, then don't allow drop.

I have tried to access the rowDrop event, but I don't have direct access to it, so I cannot call prevenDefault() on it.

Place row above the drop target

Hi, I noticed that row is placed below the drop target, if we move it to a higher position in the table.
This can be due to the code on the 220 line:

if (uiGridDraggableRowsCommon.fromIndex >= uiGridDraggableRowsCommon.toIndex) { uiGridDraggableRowsCommon.toIndex += 1; }

I would like the row to be placed above the drop target at all times, whether we move it higher or lower in the table. Could you make this logic configurable?

Thanks.

simplest codepen example from documentation broken in chromium 49

this example doesn't work in my chromium 49: http://codepen.io/skrajewski/pen/aNvWmb as can be seen in this video: https://www.youtube.com/watch?v=OrAM-B_Mx0Y (sorry for the quality, youtube downscaled it to 340p for some reason)

  • The draggable is not transparent while being dragged
  • there is no -over class added to the row while dragging.
  • No drop event is fired on the gridApi

I have no idea what the issue is.

Any help appreciated.

fromIndex and toIndex coming as -1 when trying to drag and drop

Hi,
I have basically two grids on the same page. I have some sequencing logic which works perfectly for one grid.
I wanted the same logic to be applied on my 2nd grid. Thus, called a common function onDragEnd and passed my table name to segregate my logic.

E.g.
//First Grid
var grid1Options = {
...
..
onRegisterApi: function () {
gridApi.dragRows.on.dragEnd($scope, function (draggableObject) {
onDragEnd('grid1', draggableObject);
});
}
}

// Second Grid
var grid2Options = {
...
..
onRegisterApi: function () {
gridApi.dragRows.on.dragEnd($scope, function (draggableObject) {
onDragEnd('grid2', draggableObject);
});
}
}

// my common function
function onDragEnd(sourceTable, draggableObject) {
// my logic here works perfectly for grid1 but for grid2 draggableObject gives me fromIndex and toIndex as -1
}

How to get the row.entity in the draggable-id?

Hi,
Your plugin works perfect. But only thing is that, when I drop the row I need to get the details of the source(which is being dragged) and target(To be dropped postion). How to get those? Plus the below line throws me errorin draggable-id Syntax Error: Token '{' invalid key at column 2 of the expression [{{row.id}}] starting at [{row.id}}]. when included as rowTemplate. Thanks in advance.

   rowTemplate: '<div draggable-id="{{row.id}}" grid="grid" class="ui-grid-draggable-row" draggable="true"><div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader, \'custom\': true }" ui-grid-cell></div></div>',

Nuget

Any chance of a .nuget for this?

Unable to get current target in rowDragged event

Hi, Can you please provide some way to that we can get exactly clicked element at time of drag start. we want to provide drag functionality to only one div of whole row, dragging whole row should not allow user to drag it.

I mean only one element(target element ) should allow dragging, but it should drag whole row

Thanks

a problem with draging rows in Firefox

FF does not generate the drag event unless e.dataTransfer.setData is set in the dragstart handler.
Also, in dragover handler we need to set the dropEffect property of
dataTransfer to "move", the same as we set effectAllowed in the
dragstart event. If these values didn't match the browser wouldn't let
us drop the item.
I fixed it and tested it in my local repo. Here is the diff
screen shot 2015-07-16 at 8 50 11 pm
:

Firefox issue with drag and drop (dropdowns)

Hi,

Noticed an issue with dropdowns in ui-grid and drag-drop on firefox.

If you open your dropdown and drag an option out of the grid it attempts to redirect you to 'http://move.com'.

The issue is in this line:
e.dataTransfer.setData('Text', 'Move'); // Need to set some data for FF to work

You still need this workaround but it looks like Firefox recognized 'Text' as a valid key and attempts to create a http redirect to 'Move'.

Changing this to:
e.dataTransfer.setData('foo', 'bar'); // Need to set some data for FF to work

as an example, resolves the issue.

Thanks for all the work on the plugin btw! Has made life much easier with ui-grid!

Saagar

Row dragging touch support

Hi!

First of all thank you for the great plugin.

I'm currently using it in a mobile-friendly project and I was wondering if there are any plans to do touch support any time soon, maybe by simulating mouse events ?

-Martijn

ui-grid-draggable-rows thinks my data is just a string

This issue was posted on stackoverflow: http://stackoverflow.com/q/33638477/279516

I just followed the directions to get ui-grid-draggable-rows working. They show a working example here.

My issue is that I'm getting this error:
TypeError: this.splice is not a function

At this line of code:
this.splice(to, 0, this.splice(from, 1)[0]);

Just before the splice line, I log this:
console.log(this);

This is the output:
app.Tasks

So it's a string literal. That would explain why splice isn't working. However, that string literal works in my ui-grid to display the tasks. This is in my angular controller:

$scope.gridOptions = {
data: 'app.Tasks',

So what do I do to get this to work? It seems like a conflict if the draggable plugin treats the data as a literal string, yet the grid uses that literal string to point to the array of data.

Note: In the working example referenced above, they use a hard-coded array of data as the data for the grid. That's obviously okay for an example, but not for real-world use.

Row selection does not appear

We have a grid with row selection enabled (enableRowSelection: true). When I use a custom rowTemplate with a draggable wrapper div, the selected row color doesn't change.

Looking at this issue - angular-ui/ui-grid#3013, it seems like I cannot change the levels of nesting of the divs. Is there a way to make the rows draggable but still keep the selection functionality as it is ?

Controller 'uiGrid', required by directive 'uiGridDraggableRows', can't be found!

Getting below error while trying to add this feature to angular-ui-grid.

angular.js:12477 Error: [$compile:ctreq] Controller 'uiGrid', required by directive 'uiGridDraggableRows', can't be found!
http://errors.angularjs.org/1.4.7/$compile/ctreq?p0=uiGrid&p1=uiGridDraggableRows
at angular.js:68
at getControllers (angular.js:8146)
at nodeLinkFn (angular.js:8272)
at angular.js:8519
at processQueue (angular.js:14745)
at angular.js:14761
at Scope.$eval (angular.js:15989)
at Scope.$digest (angular.js:15800)
at Scope.$apply (angular.js:16097)
at done (angular.js:10546)(anonymous function) @ angular.js:12477(anonymous function) @ angular.js:9246processQueue @ angular.js:14753(anonymous function) @ angular.js:14761$eval @ angular.js:15989$digest @ angular.js:15800$apply @ angular.js:16097done @ angular.js:10546completeRequest @ angular.js:10744requestLoaded @ angular.js:10685

Please suggest what's going wrong.

It doesn't seem to work

I've tried all the examples but none of those seems to work.
Followed the instructions with ui-grid v4.6.6 and it doesn't work either.
Do you have any working sample I can follow ?

Feature request: Drag and drop multiple rows

Hi,

thanks for the great plugin: Drag and drop for single rows works just perfect. I'm currently working on a project where I need to select multiple rows (with ui.grid.selection) and drag them all at once.

Are there any plans on implementing this feature in the near future?

Issue in IE 11 and firefox

Hi,
I have a a custom text input cell template in my grid, which should be editable with a single click like edit on focus. The editing works perfect in chrome. But the basic editing functionality gets affected in firefox and IE. I couldn't make the pointer point to a particular position of the string in the text box. The action gets blocked. Any idea why its not working in IE 11 and firefox? Thanks in advance.

Replacing ui-grid data breaks toIndex/fromIndex

Hey Szymon, great plugin!

Small issue:
When the ui-grid data is replaced with another array of data, the indices in the info object do not correspond to the correct indices anymore (indexFrom is always -1).

This is because the current assumption is that the data does not change after rendering the grid.

Drag and drop across two grids

Hi, I've tried to create a simple example of drag and drop across two grids:
https://codepen.io/anon/pen/xrVvNE
It's seems that something is missing, it detect the destination grid (I can see the dotted line) but effectively it can't drop the row in the grid.
Am I doing something wrong?

Allow dynamic dataTransfer instead of hardcoded current string

On line 99, this is hardcoded to set the data on the dataTransfer to the text string 'move'. Can you allow a parameter to be added and expose this method to allow for dynamically setting the dataTransfer data? (I would like to be able to use this feature to drag specific data from a row to a text input, and Angular is not playing nice with interpolating row data in the ui-grid templates for DOM event methods.)

Row is inserted 1 index too high.

I fixed this by using

to -= 1;

in the move() function

Am I doing something else wrong?

EDIT: I didn't like this fix because it requires patching of ui-grid-draggable-rows code, see below for a hack I ended up using.

New suggestion for the rule for moving dragged row above or below a row.

Hi, thanks for the component, very helpful. I have a suggestion for onDragOverEventListener. Instead of deciding if moving above or below a row via the offset, I think the following is more straight forward and comprehensible for the user. The way it is built now, the decision if above or below changes when moving over the middle of a row, which I personally think is too "jumpy":

  • when on a row which is above the row being dragged, you want to move it above that row
  • when on a row which is below the row being dragged, you want to move it below that row
  • when on the same row, you don't want to move the row.

So instead of checking for (offset < this.offsetHeight / 2), I did the following:

onDragOverEventListener: function (e) {
...
uiGridDraggableRowsCommon.toIndex = data().indexOf($scope.$parent.$parent.row.entity);
if (uiGridDraggableRowsCommon.toIndex < uiGridDraggableRowsCommon.fromIndex) {
...
} else if (uiGridDraggableRowsCommon.toIndex > uiGridDraggableRowsCommon.fromIndex) {
...
}
else {
$element.removeClass(uiGridDraggableRowsConstants.ROW_OVER_ABOVE_CLASS);
$element.removeClass(uiGridDraggableRowsConstants.ROW_OVER_BELOW_CLASS);
}

Any problems this could create?
Thank you

How cancel or forbid drag & drop in tree view in another branches?

Hello
Help me, please. I am using draggable with Tree View. And i need to forbid drag row to another branch. Or as variant cancel d&d if rows are in another branches or levels.

Example

$scope.gridData.onRegisterApi = function (gridApi) {
    gridApi.draggableRows.on.beforeRowMove($scope, function (from, to, data) {
        
           if (from.data.parentId != to.data.parentId)
           {
                   //action to cancel draggable
           }

    });
};

Thank you!

ui-grid row selection visualization problem

Hi Szymon,
One other issue I found has to do with row selection. I have this grid option enabled:

enableRowHeaderSelection: true

And when the ui-grid-draggable-rows plugin is used with its custom rowTemplate, my row selects activate row header checkboxes, but the row background color does not change as it normally should to a light green.
Alex

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.