Freez static column in P-table - primeng

I have a table with static actions column in first position remaining dynamic columns,
How to freeze only first actions column
For example here Name is static column and remaining are dynamic then how to freeze name column only

You could define frozen and scrollable columns as below
this.scrollableCols = [
{ field: 'year', header: 'Year' },
{ field: 'brand', header: 'Brand' },
{ field: 'color', header: 'Color' },
{ field: 'year', header: 'Year' },
{ field: 'brand', header: 'Brand' },
{ field: 'color', header: 'Color' }
];
this.frozenCols = [
{ field: 'vin', header: 'Vin' },
];
Your html would like below.
<p-table [columns]="scrollableCols" [frozenColumns]="frozenCols" [value]="cars" [scrollable]="true" scrollHeight="200px" frozenWidth="200px">
<ng-template pTemplate="colgroup" let-columns>
<colgroup>
<col *ngFor="let col of columns" style="width:200px">
</colgroup>
</ng-template>
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr>
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
Stackblitz link - https://stackblitz.com/edit/angular-primeng-frozen-columns-nytg8b?file=src/app/table-scroll-demo.component.html

Related

simple way of creating dynamic table

i have creating table with this way:
first i have my child component that act as the whole table warper
<div class="table-responsive hidden-xs">
<table class="table table-striped" :class="tableClass">
<!-- header -->
<thead class="bg-primary">
<tr class="text-nowrap">
<th v-for="item in columnData" v-if="!item.hide && !item.disable">
<div #click="sort(item.key)" v-if="item.sort" class="cursor-pointer">
<span v-html="item.title"></span>
<span v-if="params.column === item.key">
<span v-if="params.direction === 'asc'"><i class="icon-sort-amount-asc"></i></span>
<span v-else><i class="icon-sort-amount-desc"></i></span>
</span>
<span class="icon-sort text-muted" v-else></span>
</div>
<div v-else>
<span v-html="item.title"></span>
</div>
</th>
</tr>
</thead>
<!-- loading body -->
<tbody v-if="itemDataStat === 'loading'">
<tr>
<td :colspan="columnData.length">
<div class="progress">
<div class="progress-bar progress-bar-info progress-bar-striped active" style="width: 100%">
<span class="sr-only">100% Complete</span>
</div>
</div>
</td>
</tr>
</tbody>
<!-- data body -->
<tbody v-for="(items,index) in groupData" v-else-if="itemDataStat === 'success'" #contextmenu.prevent = "$refs.menu.open">
<tr class="active border-double" v-if="group.show">
<td :colspan="columnData.length">
Kelompok {{ group.title }}: <b>{{index}}</b>
</td>
</tr>
<slot name="item-desktop" v-for="(item,index) in items" :item="item" :index="index"></slot>
</tbody>
<!-- error body -->
<tbody v-else-if="itemDataStat === 'fail'">
<tr>
<td :colspan="columnData.length">
Oops.. Terjadi kesalahan, silahkan coba lagi.
</td>
</tr>
</tbody>
</table>
</div>
and from there i just import this table component into my page and just do this
<template slot="item-desktop" slot-scope="props">
<tr :class="{ 'info': selectedItem.id === props.item.id }" class="text-nowrap" #click="selectedRow(props.item)">
<td>
{{ props.index + 1 + (+itemData.current_page-1) * +itemData.per_page + '.'}}
</td>
<td v-if="!columnData[1].hide">
<img :src="'/images/' + kelas + '/' + props.item.picture + 'n.jpg'" class="img-rounded img-responsive img-sm" v-if="props.item.picture">
<img :src="'/images/no_image.jpg'" class="img-rounded img-responsive img-sm" v-else>
</td>
<td v-if="!columnData[2].hide">
<check-value :value="props.item.name"></check-value>
</td>
<td v-if="!columnData[3].hide">
<check-value :value="props.item.price1"></check-value>
</td>
<td v-if="!columnData[4].hide">
<check-value :value="props.item.price2"></check-value>
</td>
<td v-if="!columnData[5].hide">
<check-value :value="props.item.discount"></check-value>
</td>
<td v-if="!columnData[6].hide" v-html="$options.filters.dateTime(props.item.created_at)" class="text-nowrap"></td>
<td v-if="!columnData[7].hide">
<span v-if="props.item.created_at !== props.item.updated_at" v-html="$options.filters.dateTime(props.item.updated_at)"></span>
<span v-else>-</span>
</td>
</tr>
</template>
and what columnData array looked like is
columnData: [
{
title: 'No.',
key: 'No.',
excelType: 'string',
sort: false,
hide: false,
disable: false
},
{
title: 'Image',
key: 'picture',
excelType: 'string',
sort: false,
hide: false,
disable: false
},
{
title: 'Nama',
key: 'name',
excelType: 'string',
sort: true,
hide: false,
disable: false,
filter: true,
filterType: 'string',
},
{
title: 'Seller 1 Price',
key: 'price1',
excelType: 'string',
sort: true,
hide: false,
disable: false
},
{
title: 'Seller 2 Price',
key: 'price2',
excelType: 'string',
sort: true,
hide: false,
disable: false
},
{
title: 'Discount',
key: 'discount',
excelType: 'string',
sort: false,
hide: false,
disable: false
},
{
title: 'Created',
key: 'created_at',
sort: true,
hide: false,
disable: false
},
{
title: 'Updated',
key: 'updated_at',
sort: true,
hide: false,
disable: false
}
],
and i also have methods that use for hiding the column by changing columnData[].hide value to true and it will not show/hide the column header and column body
everything works fine, but when i have more and more column in one table then it will be a repetitive task. so is there any more elegant way? to just do some looping?

How to change ngTable title colors programmatically?

In this plunk I have an ngTable that is created dynamically, setting progammatically the colors of the rows for each column. How to change the colors of the column titles?
HTML:
<table ng-table-dynamic="tableParams with cols" class="table table-bordered table-hover">
<tr ng-repeat="row in data">
<td ng-repeat="col in cols" ng-style="{ 'color': col.color }">{{row[col.nm]}}</td>
</tr>
</table>
Javascript:
var app = angular.module('app', ['ngTable']);
app.controller('myCtl', function($scope,NgTableParams) {
$scope.cols = [
{nm:'uid', title:'User ID', color: 'blue'},
{nm:'ugr', title: 'Group ID', color: 'red'}
];
$scope.data = [
{ uid: 'aaa',ugr: '222'},
{ uid: 'bbb', ugr: '111'}
];
$scope.tableParams = new NgTableParams({dataset: $scope.data});
});
You can use the class property on each of the objects in your cols array:
$scope.cols = [
{nm:'uid', title:'User ID', class: 'text-blue' },
{nm:'ugr', title: 'Group ID', class: 'text-red'}
];
Then set appropriate css classes in your stylesheet:
.text-blue{
color: #0000ff;
}
.text-red{
color: #ff0000;
}
Demo Plunk
You need to include a thead. Here is an updated Plunker
<table ng-table-dynamic="tableParams with cols" class="table table-bordered table-hover">
<thead>
<tr>
<th ng-repeat="col in cols" ng-style="{ 'color': col.color }">{{col.title}}</th>
</tr>
</thead>
<tr ng-repeat="row in data">
<td ng-repeat="col in cols" ng-style="{ 'color': col.color }">{{row[col.nm]}}</td>
</tr>
</table>
The right way to do it is Matthew Cawley's answer but in case you want to do additional modifications on table headers it's useful to know that you can change template for header:
http://plnkr.co/edit/662FYVbJyz2wxqXV5nNk?p=preview
<table template-header="table-header.html" ng-table-dynamic="tableParams with cols" class="table table-bordered table-hover">
after that add file table-header.html in your project containing this:
<tr>
<th title="{{$column.headerTitle(this)}}"
ng-repeat="$column in $columns"
ng-class="{
'sortable': $column.sortable(this),
'sort-asc': params.sorting()[$column.sortable(this)]=='asc',
'sort-desc': params.sorting()[$column.sortable(this)]=='desc',
}"
ng-click="sortBy($column, $event)"
ng-if="$column.show(this)"
ng-init="template = $column.headerTemplateURL(this)"
class="header {{$column.class(this)}} {{$column.headerClass}}">
<div ng-if="!template" class="ng-table-header" ng-class="{'sort-indicator': params.settings().sortingIndicator == 'div'}">
<span ng-bind="$column.title(this)" ng-class="{'sort-indicator': params.settings().sortingIndicator == 'span'}"></span>
</div>
<div ng-if="template" ng-include="template"></div>
</th>
</tr>
then in your code:
$scope.cols = [
{nm:'uid', title:'User ID', headerClass: 'blue'},
{nm:'ugr', title: 'Group ID', headerClass: 'red'}
];
also don't forget css classes:
.red {
color: red;
}
.blue {
color: blue;
}

How to use different data inside two ng-repeat directives?

I'm trying to make an editable table directive. I have two configs:
1) Table config:
table = [
{name: 'id',title: '#'},
{name: 'name',title: 'Name'},
{name: 'phone',title: 'Phone'},
{
name: 'action',
title: 'Edit',
button_name: 'Edit me',
type: 'button',
}
];
2) Data config:
data = [
{id: 1, name: 'Rikki', phone: 02},
{id: 2, name: 'Pikki', phone: 03},
{id: 3, name: 'Mikki', phone: 03}
];
I'm wondering, how to put buttons in the cell when it's 'action' row:
3) HTML:
<thead>
<tr>
<h2>head</h2>
<td ng-repeat="(key, value) in table">{{value.title}}</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="(tkey, dataValue) in data">
<td ng-repeat="(dkey, value) in dataValue">
{{value}} // and if it's 'Action' column, I want to push data from Table config to show buttons
Is it possible? Who can help me?
<thead>
<tr>
<th ng-repeat="column in table">{{ column.title }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td ng-repeat="column in table">
<span ng-if="column.name !== 'action'">
{{ row[column.name] }}
</span>
<span ng-if="column.name === 'action'">
<button>{{ column.button_name }}</button>
</span>
</td>
</tr>
</tbody>

How to use ng-model in ng-repeat with filter?

I want to add input text box to every column of table to make filtration on table based on respective column search.
Here is my HTML code for search row of table :
<tr>
<td ng-repeat="column in columns">
<div class="right-inner-addon">
<input type="text" class="form-control input-sm" ng-model="$parent.searchTableQuery.column.field">
</div>
</td>
</tr>
Here is my filter code :
<tbody>
<tr ng-repeat="item in dataSource | filter:searchTableQuery | orderBy:predicate:reverse">
<td ng-repeat="key in getKeysOfCollection(item)">{{item[key]}}</td>
</tr>
</tbody>
But here I am not able to filter table based on table column search.
I am not able to provide valid ng-model in search input box.
ng-model="$parent.searchTableQuery.$" is ng-model of table search input box.
Update
I have updated my issue at : http://plnkr.co/edit/5vjsRdRLTFgXhvqHVkWA?p=preview
In this issue search is working only for Id column and it is not working for any other column.
Please see demo below
you can create generic filter header like below:
<tr>
<th ng-repeat="(key, value) in myArray[0]">
<input type="text" ng-model="search[key]" />
</th>
</tr>
angular.module('MyModule', [])
.controller('MyController', function($scope) {
$scope.search = {};
$scope.colors = [{
id: 11,
name: 'black',
shade: 'dark'
}, {
id: 22,
name: 'white',
shade: 'light'
}, {
id: 32,
name: 'red',
shade: 'dark'
}, {
id: 44,
name: 'blue',
shade: 'dark'
}, {
id: 5,
name: 'yellow',
shade: 'light'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='MyModule' ng-controller="MyController">
<table border="1">
<thead>
<tr>
<th ng-repeat="(key, value) in colors[0]">
<input type="text" ng-model="search[key]" />
</th>
</tr>
</thead>
<tbody>
<tr>
<tr ng-repeat="c in colors | filter:search">
<td>{{c.id}}</td>
<td>{{c.name}}</td>
<td>{{c.shade}}</td>
</tr>
</tbody>
</table>
</div>
There was invalid key issue in my above code.
I have resolved my issue based on sylwester's code as follow :
<table border="1">
<thead>
<tr>
<th ng-repeat="key in getKeysOfCollection(colors[0])">{{key}}
<input type="text" ng-model="search[key]" />
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in colors | filter:search">
<td ng-repeat="key in getKeysOfCollection(item)">{{item[key]}}</td>
</tr>
</tbody>
</table>
$scope.search = {};
$scope.colors = [{
'id': 1,
'productId': 1001,
'productName': 'prd 1',
'minimumLevel': 2,
'price': 12.50,
'productDate': '2014-11-01T06:41:30.809Z'
}, {
'id': 2,
'productId': 1002,
'productName': 'prd 2',
'minimumLevel': 23,
'price': 12.54,
'productDate': '2014-11-02T06:41:30.809Z'
}, {
'id': 3,
'productId': 1003,
'productName': 'prd 3',
'minimumLevel': 2,
'price': 12.50,
'productDate': '2014-11-04T06:41:30.809Z'
}, {
'id': 4,
'productId': 1004,
'productName': 'prd 4',
'minimumLevel': 2,
'price': 12.50,
'productDate': '2014-11-22T06:41:30.809Z'
}, {
'id': 5,
'productId': 1005,
'productName': 'prd 5',
'minimumLevel': 2,
'price': 12.50,
'productDate': '2014-11-18T06:41:30.809Z'
}];
$scope.getKeysOfCollection = function(obj) {
obj = angular.copy(obj);
if (!obj) {
return [];
}
return Object.keys(obj);
}
Now, I can filter table based on column search without specifying name of column in ng-repeat.
Working plunker is at http://plnkr.co/edit/5vjsRdRLTFgXhvqHVkWA

AngularJS - Order a table's body matching the head

I have a table
<table>
<thead>
<tr class="">
<th class="" ng-repeat="span in realm.spans">{{span.description}}</th>
</tr>
</thead>
<tbody>
<tr class="content-row" ng-repeat="row in realm.rows" ng-class="rowClass(row)" ng-click="markRow($event,row)">
<td class="content-field" ng-repeat="(i,field) in row.fields track by $index>
<input class="content-input" type="text" ng-model="row.fields[i]">
</td>
</tr>
</tbody>
</table>
How can i enforce the order used on thead, to be also used with the td elements in the table's body?
I have tried this:
<td ng-repeat="(i,field) in row.fields track by $index | orderBy: realm.spans>
<input type="text" ng-model="row.fields[i]">
</td>
But that made no change
Take a look at this sample demo
Working Demo
html
<div ng-app='myApp' ng-controller="ArrayController">
<table border="1">
<th ng-repeat="header in headers"> <b>{{ headers[$index]}}</b></th>
<tr ng-repeat="arr in records">
<td ng-repeat="val in arr" ng-bind-html-unsafe="arr[headers[$index]]">
</td>
</tr>
</table>
</div>
script
var app = angular.module('myApp', []);
app.controller('ArrayController', function ($scope) {
$scope.headers = ['col1', 'col2'];
$scope.records = [{
col1: 'a1',
col2: 'd1'
}, {
col1: 'c2',
col2: 'A2'
}, {
col1: 'b3',
col2: 'c3'
}, {
col1: 'd4',
col2: 'a1'
}, {
col1: '11',
col2: '22'
}, {
col1: 'E1',
col2: 'E2'
}];
});

Resources