使用 HTML5 和 AngularJS 拖动表格列

Posted

技术标签:

【中文标题】使用 HTML5 和 AngularJS 拖动表格列【英文标题】:Dragging a table column using HTML5 and AngularJS 【发布时间】:2014-02-19 03:32:39 【问题描述】:

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>

这里是 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
    );
   
;

);

在上面的小提琴中,我想创建一个具有列重新排序的表,我可以将列标题设置为可拖动,但是在拖动时只拖动标题的图像,我希望整个列的图像应该像拖动图像,任何建议都会有所帮助。

【问题讨论】:

我认为你需要为每一列创建一个div 感谢您的回复,虽然我试过了,但我不想向用户显示每个 div。 【参考方案1】:

以下方案适用于Chrome最新版本,本方案使用AngularJS 1.4版本实现:

代码的变化是:

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

【讨论】:

【参考方案2】:

如果您想使用插件而不是自己实现它,您可以选择:

    http://ng-table.com/

    http://ui-grid.info/

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

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

它们都支持列重新排序和许多其他功能,我相信周围还有很多其他解决方案。

【讨论】:

【参考方案3】:

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

以下是 html 代码:

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

以下是 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;  

以下是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
    );
   
;

);

因此,我创建了一个宽度为 200 像素且背景颜色为白色的框,在该框下存在“可隐藏”元素,因此它对浏览器可见,但对用户不可见。

当任意列头元素发生拖拽事件时,'hidetable'元素被设置为拖拽图片。

【讨论】:

@bmm6o 你能具体说明你遇到了什么错误吗? 也许我误解了应该发生的事情,但是 Chrome 33 中的列没有重新排序。控制台中没有错误。 有人能用它吗?我正在寻找这个功能,而这个示例在 Chrome 中对我也没有任何作用。 我相信,这里的 Asutosh 就是写这篇博客的那个人 litutech.blogspot.nl/2014/02/… 那个博客中的 plunkr 对我来说效果很好,除了我必须将 e.dataTransfer 更改为 e.originalEvent.dataTransfer【参考方案4】:

这个拖放库将为您完成:

https://github.com/lorenzofox3/lrDragNDrop

只需将其包含在您的应用中,并让您的&lt;th&gt; 说出以下内容:

<th  lr-drag-src="headers" lr-drop-target="headers" ng-repeat="hd in heads" >

【讨论】:

以上是关于使用 HTML5 和 AngularJS 拖动表格列的主要内容,如果未能解决你的问题,请参考以下文章

html5拖放背景颜色故障

如何实现拖动修改网页中div模块大小

如何使用 angularJS 将可拖动指令应用于引导模式?

HTML5拖放(Drag和Drop)元素使用详解

使用 html5 可拖动属性时保留被拖动 A 元素的外观

使用 AngularJS 控制 HTML5 视频/音频播放器的播放和暂停