Skip to content

Commit

Permalink
feat(ngTableDynamic): new directive that accepts dynamic array of col…
Browse files Browse the repository at this point in the history
…umns
  • Loading branch information
ccrowhurstram committed Feb 12, 2015
1 parent f9090b4 commit 03854d3
Show file tree
Hide file tree
Showing 3 changed files with 486 additions and 50 deletions.
115 changes: 66 additions & 49 deletions examples/demo20.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<!--[if lt IE 9]>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<![endif]-->
<script src="js/angular.min.js"></script>
<script src="../bower_components/angular/angular.js"></script>
<script src="../dist/ng-table.js"></script>
<link rel="stylesheet" href="../dist/ng-table.css">
</head>
Expand All @@ -22,47 +22,22 @@ <h1>Dynamic columns</h1>

<div ng-controller="DemoCtrl">

<p><strong>Filter:</strong> {{tableParams.filter()|json}}

Columns:
<label class="checkbox" ng-repeat="column in columns">
<input type="checkbox" ng-model="column.visible" /> {{column.title}}
<label class="checkbox" ng-repeat="column in cols">
<input type="checkbox" ng-model="column.show" /> {{column.title}}
</label>

<table ng-table="tableParams" show-filter="true" class="table">
<thead>
<tr>
<th ng-repeat="column in columns" ng-show="column.visible"
class="text-center sortable" ng-class="{
'sort-asc': tableParams.isSortBy(column.field, 'asc'),
'sort-desc': tableParams.isSortBy(column.field, 'desc')
}"
ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
<div>{{column.title}}</div>
</th>
</tr>
<tr class="ng-table-filters" ng-init="tableParams">
<th ng-repeat="column in columns" ng-show="column.visible" class="filter">
<div ng-repeat="(name, filter) in column.filter">
<div ng-if="filter.indexOf('/') !== -1" ng-include="filter"></div>
<div ng-if="filter.indexOf('/') === -1" ng-include="'ng-table/filters/' + filter + '.html'"></div>
</div>
</th>
</tr>
</thead>
<tbody>
<table ng-table-dynamic="tableParams with cols" show-filter="true" class="table table-bordered table-striped">
<tr ng-repeat="user in $data">
<td ng-repeat="column in columns" ng-show="column.visible" sortable="column.field">
{{user[column.field]}}
</td>
<td ng-repeat="col in $columns">{{user[col.field]}}</td>
</tr>
</tbody>
</table>

<script>
var app = angular.module('main', ['ngTable']).
controller('DemoCtrl', function($scope, $filter, NgTableParams) {
var data = [{name: "Moroni", age: 50},
var app = angular.module('main', ['ngTable'])
.controller('DemoCtrl', function ($scope, $filter, $q, NgTableParams) {
var data = [
{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
Expand All @@ -78,30 +53,72 @@ <h1>Dynamic columns</h1>
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.columns = [
{ title: 'Name', field: 'name', visible: true, filter: { 'name': 'text' } },
{ title: 'Age', field: 'age', visible: true }
{name: "Enos", age: 34}
];

$scope.changeNameTitle = function(){
usernameCol.title = "Crap!";
};

// terse - just return raw values
var usernameCol = {
title: 'Full Name',
titleAlt: 'Name',
sortable: 'name',
filter: { name: 'select' },
filterData: names,
show: true,
field: 'name'
};
// alternatively declare some/all column fields as functions
// your functions will receive the scope created for the header.html template as a parameter
var ageCol = {
title: 'Age',
sortable: function(/*paramsScope*/){
return 'age';
},
filter: function(/*paramsScope*/){
return {
age: 'text'
};
},
show: true,
field: 'age'
};
$scope.cols = [usernameCol, ageCol];

function names() {
var def = $q.defer(),
arr = [],
names = [];
angular.forEach(data, function(item){
if (arr.indexOf(item.name) === -1) {
arr.push(item.name);
names.push({
'id': item.name,
'title': item.name
});
}
});
def.resolve(names);
return def;
}

$scope.tableParams = new NgTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
name: 'M' // initial filter
}
count: 10 // count per page
}, {
filterDelay: 0,
total: data.length, // length of data
getData: function($defer, params) {
getData: function ($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ?
$filter('filter')(data, params.filter()) :
data;
var orderedData = params.sorting() ?
$filter('orderBy')(data, params.orderBy()) :
$filter('orderBy')(filteredData, params.orderBy()) :
data;

orderedData = params.filter() ?
$filter('filter')(orderedData, params.filter()) :
orderedData;

console.info(orderedData.length);
params.total(orderedData.length);
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
Expand Down
74 changes: 73 additions & 1 deletion src/scripts/05-directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,76 @@ app.directive('ngTable', ['$q', '$parse',
}
}
}
]);
]);

/**
* @ngdoc directive
* @name ngTable.directive:ngTableDynamic
* @restrict A
*
* @description
* A dynamic version of the {@link ngTable.directive:ngTable ngTable} directive that accepts a dynamic list of columns
* definitions to render
*/
app.directive('ngTableDynamic', ['$parse', function ($parse){

function parseDirectiveExpression(attr) {
if (!attr || attr.indexOf(" with ") > -1) {
var parts = attr.split(/\s+with\s+/);
return {
tableParams: parts[0],
columns: parts[1]
};
} else {
throw new Error('Parse error (expected example: ng-table-dynamic=\'tableParams with cols\')');
}
}

return {
restrict: 'A',
priority: 1001,
scope: true,
controller: 'ngTableController',
compile: function(tElement) {
var row;

// IE 8 fix :not(.ng-table-group) selector
angular.forEach(angular.element(tElement.find('tr')), function(tr) {
tr = angular.element(tr);
if (!tr.hasClass('ng-table-group') && !row) {
row = tr;
}
});
if (!row) {
return;
}

angular.forEach(row.find('td'), function(item) {
var el = angular.element(item);
var getAttrValue = function(attr){
return el.attr('x-data-' + attr) || el.attr('data-' + attr) || el.attr(attr);
};

// this used in responsive table
var titleExpr = getAttrValue('title');
if (!titleExpr){
el.attr('data-title-text', '{{$columns[$index].titleAlt(this) || $columns[$index].title(this)}}');
}
var showExpr = el.attr('ng-show');
if (!showExpr){
el.attr('ng-show', '$columns[$index].show(this)');
}
});

return function(scope, element, attrs, controller) {
var expr = parseDirectiveExpression(attrs.ngTableDynamic);
var columns = $parse(expr.columns)(scope) || [];
scope.$columns = controller.buildColumns(columns);

controller.setupBindingsToInternalScope(expr.tableParams);
controller.loadFilterData(scope.$columns);
controller.compileDirectiveTemplates();
};
}
};
}]);

0 comments on commit 03854d3

Please sign in to comment.