Skip to content

Commit ca77465

Browse files
manvvyasmanvesh
authored andcommitted
Fixed width support for columns and table.
Allow resizing of columns.
1 parent 531b996 commit ca77465

File tree

11 files changed

+4295
-2778
lines changed

11 files changed

+4295
-2778
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ The options object should be available on the parent scope of the `<ap-mesa>` el
117117
| showSortPriority | `boolean` | false | If true, will show a number indicating stacked sort priority of each column being sorted. |
118118
| clearFilterOnColumnHide | `boolean` | true | If true, a column's filter state will be removed when that column is hidden. |
119119
| clearSortOnColumnHide | `boolean` | true | If true, a column's sort state will be removed when that column is hidden. |
120+
| fixedWidthLayout | `boolean` | false | If true, the table's width can go beyond 100% width of the container. Use this with `lockWidth = true` for all columns. Note that horizontal scrollbars will appear for the table element. |
120121

121122
The options object is also the correct place to pass arbitrary data to table cell templates because it will be available as `options` in the table cell template scope. For example, if you want a click in a cell to call a function that is
122123
otherwise out of the scope of the table, you can do this:

app/scripts/controllers/disabled-columns.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ angular.module('apMesa.ghPage')
77
bodyHeight: 600,
88
rowPadding: 600,
99
storage: localStorage,
10-
storageKey: 'example'
10+
storageKey: 'example',
11+
fixedWidthLayout: false
1112
};
1213
this.my_table_options_paginated = angular.extend({ pagingStrategy: 'PAGINATE' }, this.my_table_options);
1314
this.my_selected_rows = [];
@@ -22,28 +23,34 @@ angular.module('apMesa.ghPage')
2223
'<i class="glyphicon glyphicon-triangle-right" ng-if="!rowIsExpanded"></i>' +
2324
'<i class="glyphicon glyphicon-triangle-bottom" ng-if="rowIsExpanded"></i>' +
2425
'{{ row.DeviceName }}' +
25-
'</a>'
26+
'</a>',
27+
width: '120px',
2628
},
2729
{
2830
id: 'brand',
2931
key: 'Brand',
3032
sort: 'string',
31-
label: 'Brand'
33+
label: 'Brand',
34+
width: '100px',
3235
},
3336
{
3437
id: 'edge',
3538
key: 'edge',
3639
label: 'Edge',
3740
sort: 'string',
38-
filter: 'like'
41+
filter: 'like',
42+
width: '120px',
3943
},
4044
{
4145
id: 'tech',
4246
key: 'technology',
4347
sort: 'string',
44-
label: 'Tech'
48+
label: 'Tech',
49+
width: '80px',
4550
}
4651
];
52+
53+
this.fixed_width_paging_scheme = 'scroll';
4754
this.my_enabled_columns = this.my_table_columns.map(function(c) { return c.id; });
4855
this.phoneData = phoneData;
4956
var _this = this;
@@ -62,4 +69,9 @@ angular.module('apMesa.ghPage')
6269
}
6370
};
6471

72+
this.toggleFixedWidth = function () {
73+
_this.my_table_options.fixedWidthLayout = !_this.my_table_options.fixedWidthLayout;
74+
_this.my_table_options_paginated.fixedWidthLayout = !_this.my_table_options_paginated.fixedWidthLayout;
75+
};
76+
6577
});

app/views/disabled-columns.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ <h3>Enabled Columns</h3>
5656

5757
<pre>{{ vm.my_enabled_columns | json }}</pre>
5858

59+
<input id="fixedWidthLayout" type="checkbox" ng-checked="(vm.pagingScheme !== 'paginate' && vm.my_table_options.fixedWidthLayout) || (vm.pagingScheme == 'paginate' && vm.my_table_options_paginated.fixedWidthLayout)" ng-click="vm.toggleFixedWidth()"/>
60+
<label for="fixedWidthLayout">options.fixedWidthLayout</label>
61+
62+
5963
</div>
6064
</div>
6165
</div>

dist/ap-mesa.css

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88

99
.ap-mesa {
1010
table-layout: fixed;
11-
width: 100%;
1211
margin-bottom: 0;
1312
}
1413

14+
.ap-mesa.full-width {
15+
width: 100%;
16+
}
17+
1518
/* the visible table header */
1619

1720
.mesa-header-table {
@@ -34,10 +37,14 @@
3437
padding: 0 !important;
3538
}
3639

37-
.mesa-rows-table-wrapper {
40+
.mesa-rows-table-wrapper.auto-layout {
3841
overflow: auto;
3942
}
4043

44+
.mesa-rows-table-wrapper.fixed-width-layout {
45+
overflow-x: visible;
46+
}
47+
4148
.mesa-rows-table > tbody + tbody {
4249
border-top: none;
4350
}
@@ -63,7 +70,7 @@
6370
/* search input */
6471

6572
.ap-mesa tr.ap-mesa-filter-row td input {
66-
width: 100%;
73+
/* width: 100%; */
6774
border-radius: 2em;
6875
border: 1px solid #CCC;
6976
outline: none;
@@ -133,7 +140,7 @@ when a discreet width has been set on it */
133140
/* wrapper for text in a th */
134141

135142
.ap-mesa th .column-text {
136-
max-width: 100%;
143+
/* max-width: 100%; */
137144
overflow: hidden;
138145
display: block;
139146
}
@@ -250,6 +257,10 @@ table tbody .ap-mesa-dummy-row td {
250257
transition-delay: 0s;
251258
}
252259

260+
.ap-mesa-overflow-x-scroll {
261+
overflow-x: scroll;
262+
}
263+
253264
.ap-mesa-loading-display.ng-enter,
254265
.ap-mesa-loading-display.ng-enter.ng-leave.ng-leave-active {
255266
opacity: 0;
@@ -338,4 +349,8 @@ table tbody .ap-mesa-dummy-row td {
338349
-webkit-box-shadow: 0 1.5em 0 0;
339350
box-shadow: 0 1.5em 0 0;
340351
}
352+
}
353+
354+
.table-nonfluid {
355+
width: auto !important;
341356
}

dist/ap-mesa.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ angular.module('apMesa.controllers.ApMesaController', [
462462
'glyphicon glyphicon-chevron-down'
463463
],
464464
onRegisterApi: function (api) {
465-
}
465+
},
466+
fixedWidthLayout: false
466467
};
467468
function defaults(obj) {
468469
if (typeof obj !== 'object') {
@@ -596,6 +597,7 @@ angular.module('apMesa.controllers.ApMesaController', [
596597
function postLink(scope, element) {
597598
var deregStorageWatchers = [];
598599
scope.scrollDiv = element.find('.mesa-rows-table-wrapper');
600+
scope.wrapperDiv = element.find('.ap-mesa-wrapper');
599601
scope.$watch('_columns', function (columns, oldColumns) {
600602
if (columns !== scope.columns) {
601603
resetColumns(scope);
@@ -639,6 +641,24 @@ angular.module('apMesa.controllers.ApMesaController', [
639641
resetState(scope);
640642
initOptions(scope);
641643
});
644+
scope.$watch('options.fixedWidthLayout', function (newValue, oldValue) {
645+
if (newValue !== oldValue) {
646+
if (angular.isString(scope.classes)) {
647+
if (newValue && scope.classes.indexOf('table-nonfluid') === -1) {
648+
scope.classes = scope.classes + ' table-nonfluid';
649+
} else if (!newValue && scope.classes.indexOf('table-nonfluid') > -1) {
650+
scope.classes = scope.classes.split('table-nonfluid').join('');
651+
}
652+
if (!newValue && scope.classes.indexOf('full-width') === -1) {
653+
scope.classes = scope.classes + ' full-width';
654+
} else if (newValue && scope.classes.indexOf('full-width') > -1) {
655+
scope.classes = scope.classes.split('full-width').join('');
656+
}
657+
}
658+
resetState(scope);
659+
initOptions(scope);
660+
}
661+
});
642662
scope.$watch('options.storage', function (storage) {
643663
if (storage) {
644664
if (!scope.options.storageKey) {
@@ -2182,7 +2202,7 @@ angular.module('apMesa.templates', [
21822202
angular.module('src/templates/apMesa.tpl.html', []).run([
21832203
'$templateCache',
21842204
function ($templateCache) {
2185-
$templateCache.put('src/templates/apMesa.tpl.html', '<div class="ap-mesa-wrapper" ng-class="{\n' + '\'paging-strategy-paginate\': options.pagingStrategy === \'PAGINATE\',\n' + '\'paging-strategy-scroll\': options.pagingStrategy === \'SCROLL\',\n' + '\'ap-mesa-loading-error\': !!transientState.loadingError,\n' + '\'ap-mesa-no-data\': !transientState.loading && !transientState.loadingError && visible_rows.length === 0\n' + '}">\n' + ' <table ng-class="classes" class="ap-mesa mesa-header-table">\n' + ' <thead>\n' + ' <!-- MAIN ROW OF COLUMN HEADERS -->\n' + ' <tr ui-sortable="sortableOptions" ng-model="enabledColumnObjects" class="ap-mesa-header-row">\n' + '\n' + ' <!-- COLUMN HEADERS -->\n' + ' <th\n' + ' scope="col"\n' + ' ng-repeat="column in enabledColumnObjects"\n' + ' ng-click="toggleSort($event,column)"\n' + ' ng-class="[\n' + ' {\n' + ' \'sortable-column\' : column.sort,\n' + ' \'select-column\': column.selector,\n' + ' \'is-sorting\': sortDirection[column.id]\n' + ' },\n' + ' \'table-header-\' + column.id,\n' + ' column.classes ? column.classes : \'\'\n' + ' ]"\n' + ' ng-attr-title="{{ column.title || \'\' }}"\n' + ' ng-style="{ width: column.width, \'min-width\': column.width, \'max-width\': column.width }">\n' + '\n' + ' <!-- COLUMN TEXT -->\n' + ' <span class="column-text">\n' + ' <input ng-if="column.selector" type="checkbox" ng-checked="isSelectedAll()" ng-click="toggleSelectAll($event)" />\n' + ' <span\n' + ' class="ap-mesa-sort-icon" \n' + ' ng-if="column.sort"\n' + ' title="This column is sortable. Click to toggle sort order. Hold shift while clicking multiple columns to stack sorting.">\n' + ' <span class="sorting-icon {{ getSortClass( sortDirection[column.id] ) }}"></span>\n' + ' <span ng-bind="transientState.sortPriority[column.id]" class="sort-priority" ng-if="transientState.sortPriorityShow && transientState.sortPriority[column.id]"></span>\n' + ' </span>\n' + ' <span class="ap-mesa-th-title" ap-mesa-th-title></span>\n' + ' </span>\n' + '\n' + ' <!-- COLUMN RESIZER -->\n' + ' <span\n' + ' ng-if="!column.lockWidth"\n' + ' class="column-resizer"\n' + ' ng-class="{\'discreet-width\': !!column.width}"\n' + ' title="Click and drag to set discreet width. Click once to clear discreet width."\n' + ' ng-mousedown="startColumnResize($event, column)">\n' + ' &nbsp;\n' + ' </span>\n' + '\n' + ' </th>\n' + ' </tr>\n' + '\n' + ' <!-- ROW OF COLUMMN FILTERS -->\n' + ' <tr ng-if="hasFilterFields() && transientState.showFiltersRow" class="ap-mesa-filter-row">\n' + '\n' + ' <!-- COLUMN FILTER CELLS -->\n' + ' <td ng-repeat="column in enabledColumnObjects" ng-class="\'column-\' + column.id">\n' + '\n' + ' <!-- FILTER INPUT -->\n' + ' <input\n' + ' type="text"\n' + ' ng-if="(column.filter)"\n' + ' ng-model="persistentState.searchTerms[column.id]"\n' + ' ng-attr-placeholder="{{ column.filterPlaceholder ? column.filterPlaceholder : (column.filter.placeholder || \'filter\') }}"\n' + ' ng-attr-title="{{ column.filter && column.filter.title }}"\n' + ' ng-class="{\'active\': persistentState.searchTerms[column.id] }">\n' + '\n' + ' <!-- FILTER CLEAR BUTTON -->\n' + ' <button\n' + ' ng-if="(column.filter)"\n' + ' ng-show="persistentState.searchTerms[column.id]"\n' + ' class="clear-search-btn"\n' + ' role="button"\n' + ' type="button"\n' + ' ng-click="clearAndFocusSearch(column.id)">\n' + ' &times;\n' + ' </button>\n' + '\n' + ' </td>\n' + ' </tr>\n' + ' </thead>\n' + ' </table>\n' + ' <div ap-mesa-status-display></div>\n' + ' <div class="mesa-rows-table-wrapper" ng-style="tbodyNgStyle" ng-hide="transientState.loadingError">\n' + ' <table ng-class="classes" class="ap-mesa mesa-rows-table">\n' + ' <thead>\n' + ' <th\n' + ' scope="col"\n' + ' ng-repeat="column in enabledColumnObjects"\n' + ' ng-style="{ width: column.width, \'min-width\': column.width, \'max-width\': column.width }"\n' + ' ></th>\n' + ' </tr>\n' + ' </thead>\n' + ' <tbody ng-if="options.pagingStrategy === \'SCROLL\'" ap-mesa-dummy-rows="[0,transientState.rowOffset]" cell-content="..."></tbody>\n' + ' <tbody ap-mesa-rows class="ap-mesa-rendered-rows"></tbody>\n' + ' <tbody ng-if="options.pagingStrategy === \'SCROLL\'" ap-mesa-dummy-rows="[transientState.rowOffset + visible_rows.length, transientState.filterCount]" cell-content="..."></tbody>\n' + ' </table>\n' + ' </div>\n' + ' <div class="ap-mesa-pagination" ng-if="options.pagingStrategy === \'PAGINATE\'" ap-mesa-pagination-ctrls></div>\n' + '</div>\n' + '');
2205+
$templateCache.put('src/templates/apMesa.tpl.html', '<div>\n' + ' <div class="ap-mesa-wrapper" ng-class="{\n' + ' \'paging-strategy-paginate\': options.pagingStrategy === \'PAGINATE\',\n' + ' \'paging-strategy-scroll\': options.pagingStrategy === \'SCROLL\',\n' + ' \'ap-mesa-loading-error\': !!transientState.loadingError,\n' + ' \'ap-mesa-no-data\': !transientState.loading && !transientState.loadingError && visible_rows.length === 0\n' + ' }" ng-style="{ \'overflow-x\': options.fixedWidthLayout ? \'scroll\' : \'visible\' }">\n' + ' <table ng-class="classes" class="ap-mesa mesa-header-table">\n' + ' <thead>\n' + ' <!-- MAIN ROW OF COLUMN HEADERS -->\n' + ' <tr ui-sortable="sortableOptions" ng-model="enabledColumnObjects" class="ap-mesa-header-row">\n' + '\n' + ' <!-- COLUMN HEADERS -->\n' + ' <th\n' + ' scope="col"\n' + ' ng-repeat="column in enabledColumnObjects"\n' + ' ng-click="toggleSort($event,column)"\n' + ' ng-class="[\n' + ' {\n' + ' \'sortable-column\' : column.sort,\n' + ' \'select-column\': column.selector,\n' + ' \'is-sorting\': sortDirection[column.id]\n' + ' },\n' + ' \'table-header-\' + column.id,\n' + ' column.classes ? column.classes : \'\'\n' + ' ]"\n' + ' ng-attr-title="{{ column.title || \'\' }}"\n' + ' ng-style="{ width: options.fixedWidthLayout ? \'auto\' : column.width, \'min-width\': column.width, \'max-width\': column.width }">\n' + '\n' + ' <!-- COLUMN TEXT -->\n' + ' <span class="column-text">\n' + ' <input ng-if="column.selector" type="checkbox" ng-checked="isSelectedAll()" ng-click="toggleSelectAll($event)" />\n' + ' <span\n' + ' class="ap-mesa-sort-icon" \n' + ' ng-if="column.sort"\n' + ' title="This column is sortable. Click to toggle sort order. Hold shift while clicking multiple columns to stack sorting.">\n' + ' <span class="sorting-icon {{ getSortClass( sortDirection[column.id] ) }}"></span>\n' + ' <span ng-bind="transientState.sortPriority[column.id]" class="sort-priority" ng-if="transientState.sortPriorityShow && transientState.sortPriority[column.id]"></span>\n' + ' </span>\n' + ' <span class="ap-mesa-th-title" ap-mesa-th-title></span>\n' + ' </span>\n' + '\n' + ' <!-- COLUMN RESIZER -->\n' + ' <span\n' + ' ng-if="!column.lockWidth"\n' + ' class="column-resizer"\n' + ' ng-class="{\'discreet-width\': !!column.width}"\n' + ' title="Click and drag to set discreet width. Click once to clear discreet width."\n' + ' ng-mousedown="startColumnResize($event, column)">\n' + ' &nbsp;\n' + ' </span>\n' + '\n' + ' </th>\n' + ' </tr>\n' + '\n' + ' <!-- ROW OF COLUMMN FILTERS -->\n' + ' <tr ng-if="hasFilterFields() && transientState.showFiltersRow" class="ap-mesa-filter-row">\n' + '\n' + ' <!-- COLUMN FILTER CELLS -->\n' + ' <td ng-repeat="column in enabledColumnObjects" ng-class="\'column-\' + column.id">\n' + '\n' + ' <!-- FILTER INPUT -->\n' + ' <input\n' + ' type="text"\n' + ' ng-if="(column.filter)"\n' + ' ng-model="persistentState.searchTerms[column.id]"\n' + ' ng-attr-placeholder="{{ column.filterPlaceholder ? column.filterPlaceholder : (column.filter.placeholder || \'filter\') }}"\n' + ' ng-attr-title="{{ column.filter && column.filter.title }}"\n' + ' ng-class="{\'active\': persistentState.searchTerms[column.id] }"\n' + ' ng-style="{\'width\': options.fixedWidthLayout ? column.width : \'100%\'}">\n' + '\n' + ' <!-- FILTER CLEAR BUTTON -->\n' + ' <button\n' + ' ng-if="(column.filter)"\n' + ' ng-show="persistentState.searchTerms[column.id]"\n' + ' class="clear-search-btn"\n' + ' role="button"\n' + ' type="button"\n' + ' ng-click="clearAndFocusSearch(column.id)">\n' + ' &times;\n' + ' </button>\n' + '\n' + ' </td>\n' + ' </tr>\n' + ' </thead>\n' + ' </table>\n' + ' <div ap-mesa-status-display></div>\n' + ' <div class="mesa-rows-table-wrapper" ng-style="tbodyNgStyle" ng-hide="transientState.loadingError"\n' + ' ng-class="{\n' + ' \'fixed-width-layout\': options.fixedWidthLayout,\n' + ' \'auto-layout\': !options.fixedWidthLayout\n' + ' }">\n' + ' <table ng-class="classes" class="ap-mesa mesa-rows-table">\n' + ' <thead>\n' + ' <colgroup ng-if="options.fixedWidthLayout">\n' + ' <col ng-repeat="column in enabledColumnObjects"\n' + ' ng-style="{ width: column.width }"\n' + ' />\n' + ' </colgroup>\n' + ' <th\n' + ' scope="col"\n' + ' ng-repeat="column in enabledColumnObjects"\n' + ' ng-style="{ width: options.fixedWidthLayout ? \'auto\' : column.width, \'min-width\': column.width, \'max-width\': column.width }"\n' + ' ></th>\n' + ' </tr>\n' + ' </thead>\n' + ' <tbody ng-if="options.pagingStrategy === \'SCROLL\'" ap-mesa-dummy-rows="[0,transientState.rowOffset]" cell-content="..."></tbody>\n' + ' <tbody ap-mesa-rows class="ap-mesa-rendered-rows"></tbody>\n' + ' <tbody ng-if="options.pagingStrategy === \'SCROLL\'" ap-mesa-dummy-rows="[transientState.rowOffset + visible_rows.length, transientState.filterCount]" cell-content="..."></tbody>\n' + ' </table>\n' + ' </div>\n' + ' </div>\n' + ' <div class="ap-mesa-pagination" ng-if="options.pagingStrategy === \'PAGINATE\'" ap-mesa-pagination-ctrls></div>\n' + '</div>');
21862206
}
21872207
]);
21882208
angular.module('src/templates/apMesaDummyRows.tpl.html', []).run([

0 commit comments

Comments
 (0)