Search code examples
angularjshtml5-draggable

Dragging a table column using HTML5 and AngularJS


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.


Solution

  • 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.