ng-table - 如何合并同一标题下的列?

时间:2017-11-28 14:03:58

标签: angularjs merge header

我需要在列'a + b'上方有一个标题,然后,在第一个标题下方,标题为'a',另一个标题为'b'。像这样:

+-------------+---------------+
|   headerAB  |     HdrC      |
+-------------+               |
| HdrA | HdrB |               |
+-------------+---------------+
   a1    b1           c1 
   a2    b2           c2   
   a3    b3           c3 
   a4    b4           c4  

我还需要对可乐和colb使用“filter =”和“sortable =”选项。

我搜索了很多,没有成功。 NG-TABLE似乎没有为此提供解决方案。

我可以在单个标题下嵌套2列,并且仍然保持过滤器和可排序选项的完美运行吗?

感谢。

1 个答案:

答案 0 :(得分:0)



angular.module('myApp', [])
  .controller('MyCtrl', function(PaginationModel, DataService){
    var ctrl = this;
    ctrl.DataService = DataService;
    ctrl.maxPageButtons = 5;
    ctrl.abFilter = function(value, index, array) {
      if(!ctrl.abSearch)
        return true;
      return value.a == ctrl.abSearch || value.b == ctrl.abSearch;
    };
  })
  
  .service('DataService', function(){
    var dataService = { data: [] };
    
    for(var i=0; i<1000; i++){
      var randA = Math.floor(Math.random()*50);
      var randB = Math.floor(Math.random()*50);
      var randC = Math.floor(Math.random()*50);
      dataService.data.push({pos:i, a:randA,b:randB,c:randC});
    }
    
    return dataService; 
  })
  
  .directive('pagingDisplay', function(){
    return {
      scope:{
        startAt: '=',       //Two way binding for which element to start at
        numPerPage: '@',    //Number of elements we want per page
        totalElements: '@',  //Total number of elements in the collection
        maxButtons:'@'      //Maximum number of page number buttons to show
      },
      templateUrl:'templateId.html',
      link:function(scope, iElem, iAttrs){
        //Computed when the num per page and total are provided
        var _totalPages = 0;  
        
        //Max page buttons to show (default 5)
        var _maxPages = 5;
        scope.model = {
          selectedPage: 0,
          showForward:false,
          showBackward:true
         };
        
        /**
        * Uses the current selected page, num pages, and max pages to
        * create an array that corresponds to the page numbers shown
        */
        function genPagesArray(numPages){
          scope.pages = [];
          
          if(numPages<=_maxPages)
          {
            for(var i=0; i<numPages; i++){
              scope.pages.push(i);
            }
          }
          else {
            var showEndPage = true, showStartPage = true;
            var halfPages = Math.floor((_maxPages-1)/2);
            
            var firstPage = Math.max(0, scope.model.selectedPage-halfPages);
            var lastPage = firstPage+_maxPages;
            
            if(lastPage > _totalPages)
            {
            
              firstPage += (_totalPages - lastPage);
              lastPage = _totalPages;
            }
            
            for(var i=firstPage, x=0; i<lastPage && x<_maxPages; x++, i++){
              scope.pages.push(i)
              
              if(i==numPages-1)
                showEndPage = false;
              if(i==0)
                showStartPage = false;
            }
            
            if(showEndPage)
            {
              scope.pages.pop();
              scope.pages.push(numPages-1);
            }
            if(showStartPage)
            {
              scope.pages.shift();
              scope.pages.unshift(0);
            }
          }
        }
        genPagesArray(5);
        
        scope.$watch('totalElements', function(newVal){
          var intVal = scope.totalElements;
          if(intVal && !isNaN(intVal = parseInt(intVal))){
            _totalPages = Math.ceil(intVal / scope.numPerPage)
            if(scope.model.selectedPage > _totalPages)
            {
              scope.firstPage();
            }
            else{
              genPagesArray(_totalPages);
            }
          }
        });
        
        scope.$watch('maxButtons', function(newVal){
          var intVal = scope.maxButtons;
          if(intVal && !isNaN(intVal = parseInt(intVal))){
            _maxPages = intVal;
            genPagesArray(_totalPages);
          }
        });
        
        scope.prevPage = function(){
          if(scope.model.selectedPage>0)
            scope.changeSelectedPage(scope.model.selectedPage-1)
        }
        scope.nextPage = function(){
          if(scope.model.selectedPage<_totalPages-1)
            scope.changeSelectedPage(scope.model.selectedPage+1)
        }
        scope.lastPage = function(){
          scope.changeSelectedPage(_totalPages-1)
        }
        scope.firstPage = function(){
          scope.changeSelectedPage(0)
        }
        
        scope.changeSelectedPage = function(pageToSelect){
          scope.model.selectedPage = pageToSelect;
          scope.startAt = pageToSelect*parseInt(scope.numPerPage);
          genPagesArray(_totalPages)
        }
      }
    }
  })
  
  .service('PaginationModel', function(){
    var serv = { curPage: 0, numPage: NaN};
    return serv;
  })
  ;
&#13;
.pagination-button{
  border: 1px solid #ccc;
  border-radius: 4px;
  padding:10px;
  display:inline-block;
  width: 20px;
  text-align:center;
  
  margin-right:2px;
  
  
  /* Disable Text Selection */
  -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome and Opera */
}

.pagination-button:hover{
  background-color: #ddffdd;
  cursor:pointer;
}

.pagination-button:active, .pagination-button.selected{
  background-color: #ccffaa;
}

table{
  width:100%;
}
table, th, td {
  border:1px solid gray;
  border-collapse:collapse;
}
&#13;
<!DOCTYPE html>
<html ng-app="myApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script>

<script type="text/ng-template" id="templateId.html">
<div>
  <span class="pagination-button" ng-click="firstPage()"> |< </span><span class="pagination-button" ng-click="prevPage()"> << </span><span class="pagination-button" 
    ng-click="changeSelectedPage(page)" 
    ng-class="{'selected':model.selectedPage == page}" 
    ng-repeat="page in pages track by $index">
    {{(page+1)}}
  </span><span class="pagination-button" ng-click="nextPage()"> >> </span><span class="pagination-button" ng-click="lastPage()"> >| </span>
</div>
</script>

<body>

<div>
  <div ng-controller="MyCtrl as myctrl">
    <table>
      <thead>
        <tr>
          <td>#</td>
          <td colspan="2">a and b <input type="text" ng-model="myctrl.abSearch"/></td>
          <td>c</td>
        </tr>
        <tr>
          <td>#</td>
          <td>a</td>
          <td>b</td>
          <td>c</td>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="datum in myctrl.filtered = (myctrl.DataService.data | filter:myctrl.abFilter) | limitTo: 5 : myctrl.startAt">
          <td>{{::datum.pos}}</td>
          <td>{{::datum.a}}</td>
          <td>{{::datum.b}}</td>
          <td>{{::datum.c}}</td>
        </tr>
      </tbody>
    </table>
    <paging-display num-per-page="5" max-buttons="{{myctrl.maxPageButtons}}" total-elements="{{myctrl.filtered.length}}" start-at="myctrl.startAt">
    </paging-display>
    
    <h1>Buttons to show</h1>
    <input type="number" min="1" max="100" ng-model="myctrl.maxPageButtons"/>
  </div>
</div>

</body>
</html>
&#13;
&#13;
&#13;