3

http://jsfiddle.net/asutosh/82qum/

<div ng-app='myApp'>

 <div ng-controller="myCtrl">


<table border="4">
    <thead>
        <th ng-repeat="hd in heads">
            <div draganddrop drag="handleDrag()">{{hd}}</div>
        </th>
        </thead>
        <tr ng-repeat="row in myData">
        <td ng-repeat="hd in heads">
        {{row[hd]}}
        </td>
        </tr>

</table>
</div>

Here is the JS:

  var myApp=angular.module('myApp',[]);
  myApp.controller('myCtrl',function($scope){
  $scope.handleDrag=function()
     {

     }


   $scope.heads=['name','age','company','tech'];

   $scope.myData=[{name:'Jay',age:27,company:'XYZ',tech:'Js'},
            { name:'Rayn',age:30,company:'XYZ',tech:'.net'}]    
   });
    myApp.directive('draganddrop',function(){
    return{
    scope:{
        drag:'&'
    },  
    link: function(scope, element) {
    // this gives us the native JS object
    var el = element[0];
     el.draggable=true;

    el.addEventListener(
        'dragstart',
        function(e) {


    e.dataTransfer.effectAllowed = 'move';

           // this.classList.add('drag');
            return false;
        },
        false
    );

    el.addEventListener(
        'dragend',
        function(e) {

            this.classList.remove('drag');
            return false;
        },
        false
    );
}   
};

});

In the above fiddle I want to create a table having column reordering, I am able to set the column header to draggable however while dragging only the header's image is getting dragged, I want the the image of the whole column should come as the dragging image, any suggestion on that will be helpful.

Asutosh
  • 1,775
  • 2
  • 15
  • 22

4 Answers4

5

The following solution works with Chrome's latest version, and this solution is implemented using AngularJS 1.4 version:

The change in the code is:

var headerElem=e.target.closest('th');
          var textOfHeader=angular.element(headerElem).find("a");
          scope.$apply(function() {
            scope[dropfn](data, textOfHeader[0]);
          });

http://plnkr.co/VDygHR

Jace Rhea
  • 4,982
  • 4
  • 36
  • 55
Asutosh
  • 1,775
  • 2
  • 15
  • 22
2

If you want to use a plugin instead of implementing it yourself you can choose from:

  1. http://ng-table.com/

  2. http://ui-grid.info/

  3. http://lorenzofox3.github.io/smart-table-website/

  4. http://ekokotov.github.io/object-table/

They all support column reorder and a lot of other features, I believe there are a lot of other solutions around.

Herbi Shtini
  • 2,002
  • 29
  • 34
1

http://jsfiddle.net/asutosh/82qum/142/

Following is HTML Code:

 <div ng-app='myApp'>
  <div ng-controller="myCtrl">    
  <table ng-hide={{dragStart}} id="hidtable" border="4" >
   <thead>

       <th>{{dragHead}}</th>
   </thead>
   <tr ng-repeat="row in myData">
       <td>{{row[dragHead]}}</td>
   </tr>
</table>
<div class='dragstyle' id="coverup"></div>
<table border="4">
    <thead>
        <th ng-repeat="hd in heads">
            <div draganddrop drag="handleDrag">{{hd}}</div>
        </th>
        </thead>
        <tr ng-repeat="row in myData">
        <td ng-repeat="hd in heads">
        {{row[hd]}}
        </td>
        </tr>

</table>
</div>
</div>

Following is the CSS:

.dragstyle{
background: white;
width:200px;
color:white;   
height: 100px;
position: absolute;
top: 0;
right: 0;
z-index: 2;
}
#hidtable{  
height: 100px;
position: absolute;
top: 0;
right: 0;
z-index: 2;  
}

Following is the JS:

var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',function($scope){
$scope.handleDrag=function(columnName)
{

  $scope.dragHead=columnName;

};

$scope.dragHead='name';

$scope.heads=['name','age','company','tech'];

$scope.myData=[{name:'Jay',age:27,company:'XYZ',tech:'Js'},
{name:'Rayn',age:30,company:'XYZ',tech:'.net'}]    
});
myApp.directive('draganddrop',function(){
return{
    scope:{
        drag:'='
},  
    link: function(scope, element,attrs) {

    var el = element[0];
     el.draggable=true;

    el.addEventListener(
        'dragstart',
        function(e) {

             e.dataTransfer.effectAllowed = 'move';
             var  columnName=e.target.innerHTML;                    
            scope.$apply(function(self){
                console.log(self);
           scope.drag(columnName);

            });                 

            e.dataTransfer.setDragImage(document.getElementById('hidtable'), 0, 0);
          ;
            return false;
        },
        false
    );

    el.addEventListener(
        'dragend',
        function(e) {

            this.classList.remove('drag');

            return false;
        },
        false
    );
}   
};

});

So this way I have created a box with width of 200px and having background color as white, under that the 'hidetable' element is present, so it's visible to the browser but not to the user.

When the drag event occurs at any column head element, the 'hidetable' element is set as the drag image.

Asutosh
  • 1,775
  • 2
  • 15
  • 22
  • @bmm6o Can you please specify what error u r getting? – Asutosh Mar 25 '14 at 05:14
  • 1
    Maybe I'm misunderstanding what's supposed to happen, but the columns don't reorder in Chrome 33. No error in the console. – bmm6o Mar 25 '14 at 15:48
  • Anyone ever get this to work? I'm looking for this functionality, and this example does nothing in Chrome for me as well. – Tim Hardy Jun 30 '15 at 18:41
  • I believe, the Asutosh here is the same one who blogged this http://litutech.blogspot.nl/2014/02/an-angular-table-directive-having.html The plunkr in that blog worked well for me, except that I had to change `e.dataTransfer` to `e.originalEvent.dataTransfer` – Mubin Aug 14 '16 at 20:17
0

This drag'n'drop library will do it for you:

https://github.com/lorenzofox3/lrDragNDrop

Just include it in your app, and make your <th> say this:

<th  lr-drag-src="headers" lr-drop-target="headers" ng-repeat="hd in heads" >
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Frazer Kirkman
  • 1,003
  • 1
  • 14
  • 23