I'm submitting a ... (check one with "x")
[ ] bug report => Search github for a similar issue or PR before submitting
[ X ] feature request => Please check if request is not on the roadmap already https://github.com/primefaces/primeng/wiki/Roadmap
[ ] support request => Please do not submit support request here, instead see http://forum.primefaces.org/viewforum.php?f=35
Current behavior
Current have a row style function "rowStyleClass", but not have a cell style function maybe like "cellStyleClass" and so on.
Expected behavior
add a cellStyleClass that :
"gets the row data and row index as parameters and returns a style class for the cell".
that function can return a style class to change cell background-color and so on.
Minimal reproduction of the problem with instructions
only add a cellStyleClass like rowStyleClass at the <td> element in datatable.ts 's line 162: TableBody compoment's template html. and add support function in the DataTable compoment like getRowStyleClass function.
What is the motivation / use case for changing the behavior?
example, change cell background-color to make a color-full timetable.
use div in template cannot fill the full cell.
Please tell us about your environment:
latest WebStorm
Language: [all | TypeScript X.X | ES6/7 | ES5]
all
i use follow hack directive to solution it, so, i think i dont need it now !!
import {Directive, ElementRef, OnInit, Renderer, Input, OnDestroy, Output, EventEmitter} from '@angular/core';
import * as _ from 'lodash';
import {ReplaySubject, Subscription} from "rxjs";
export type ParentFinderType = (startNode: Node) => Node|null;
@Directive({
selector: '[ccParentsSetter]'
})
export class ParentsSetterDirective implements OnInit,OnDestroy {
@Input('classObject') set classObject(value: {[className: string]: boolean}) {
this.classObjectSubject.next(value);
}
@Input('styleObject') set styleObject(value: {[styleName: string]: string}) {
this.styleObjectSubject.next(value);
}
@Input('attributeObject') set attributeObject(value: {[attributeName: string]: string}) {
this.attributeObjectSubject.next(value);
}
@Input('customParentFinder') customParentFinder: ParentFinderType;
@Input('customNode') customNode: Node;
@Input() onClickParam: any;
@Output('ccParentsSetterOnClick') onClick: EventEmitter<{param: any, $event: Event}> = new EventEmitter();
private onClickListenUnhookFunc: Function|undefined;
// cold Subject
classObjectSubject: ReplaySubject<any> = new ReplaySubject();
styleObjectSubject: ReplaySubject<any> = new ReplaySubject();
attributeObjectSubject: ReplaySubject<any> = new ReplaySubject();
classObjectSubjectSubscription: Subscription;
styleObjectSubjectSubscription: Subscription;
attributeObjectSubjectSubscription: Subscription;
constructor(private elementRef: ElementRef,
private renderer: Renderer) {
}
isInit = false;
ngOnInit() {
let node = null;
if (this.customNode instanceof Node) {
node = this.customNode;
} else {
if (_.isFunction(this.customParentFinder)) {
node = this.customParentFinder(this.elementRef.nativeElement);
} else {
let parentFinder = (node: Node, level: number = 0): Node|null => {
return (node && level < 10) ? (
node.nodeName == "TD" ? node : parentFinder(node.parentNode, level + 1)
) : null;
};
node = parentFinder(this.elementRef.nativeElement);
}
}
if (node) {
this.onClickListenUnhookFunc = this.renderer.listen(node, "click", ($event: Event) => {
this.onClick.emit({param: this.onClickParam, $event: $event});
});
this.classObjectSubjectSubscription = this.classObjectSubject.subscribe(
next => {
_.forIn(next, (v, k) => {
this.renderer.setElementClass(node, k, v);
});
}
);
this.styleObjectSubjectSubscription = this.styleObjectSubject.subscribe(
next => {
_.forIn(next, (v, k) => {
this.renderer.setElementStyle(node, k, v);
});
}
);
this.attributeObjectSubjectSubscription = this.attributeObjectSubject.subscribe(
next => {
_.forIn(next, (v, k) => {
this.renderer.setElementAttribute(node, k, v);
});
}
);
this.isInit = true;
}
if (!node || !this.isInit) {
console.error("ParentsSetterDirective cannot init.");
console.error("ParentsSetterDirective maybe not work.");
}
}
ngOnDestroy() {
if (this.isInit) {
this.classObjectSubjectSubscription.unsubscribe();
this.styleObjectSubjectSubscription.unsubscribe();
this.attributeObjectSubjectSubscription.unsubscribe();
if (this.onClickListenUnhookFunc) {
this.onClickListenUnhookFunc();
}
}
}
}
use it as follow
<p-dataTable>
<p-column [field]="ld">
<template let-col let-rd="rowData" let-ri="rowIndex" pTemplate="body">
<div
class="text-center"
ccParentsSetter
[classObject]="countStyleClass(rd,col,ri)"
(ccParentsSetterOnClick)="tdClick(rd,col,ri)"
>
</div>
</template>
</p-column>
</p-dataTable>
close it, please :(
I have found a way to change background the color of the column.
Please let me know if I have done it the correct way or need some improvement.
Below is my code :
HTML Code:
<p-column header="ID" >
<template let-data="rowData" pTemplate="body">
<span #x> {{ getColor(x,data) }} {{ data.id }}</span>
</template>
</p-column>
TS Code:
// just a sample code, to assign background color depending on our required criteria
getColor(x, data) {
var color: string;
if (data.status === 1) {
color = 'lightgreen';
} else if (data.status === 2) {
color = 'lightblue';
}
x.parentNode.parentNode.style.background = color; // x.parentNode.parentNode accesses the <td> element of table :)
}
Here is the output:
Hope this helps!!
Thanks
@supriya2992 it's work well but i dont like it as ParentsSetterDirective way.
because this is a hack way and cannot work well when dom struct change.
Better to use column style and styleClass.
can you post an example using column style and styleClass that accomplishes the same results please
@gjenner
@cagataycivici
But if you need control every cell's color, the column style will not enough. Example to write a simple colorfull task table.
you stated "Better to use column style and styleClass, just looking for an example of @supriya2992 's solution in your suggested method
yea, I use the ParentsSetterDirective as long as 4 mouth. ㄟ( ▔, ▔ )ㄏ
@cagataycivici I use styleClass
<p-column field="ExpirationDate" header="Expiration Date" [sortable]="true" [styleClass]="checkStyleClass">
and in ts.
public checkStyleClass(item: Client){
...
}
but the function is not fired
@pantonis try to use
[styleClass]="checkStyleClass()"
I think this should be reopened, since the solution mentioned here is still just a hacky workaround and nobody could post a working solution with styleClass.
+1
I guess the issue isn't a "simple feature request" after all since the latest pull request got denied because of performance impacts when calling a function for every table cell.
See #4463.
@cagataycivici Would you please reopen this issue. I need more attention for this feature. As of now, I am still using the hacky workaround described above but I can't add a new feature request for my application (dynamically configurable columns) without losing colored cells (which are mandatory) because the workaround is based on angular template reference variables which are static only and can't be dynamic.
@denniseffing I think your question need a way to control any special table cell by the table compoment ref on parents compoment's TS code.
i think you need a way to get a cell by the coordinates of the cell and the table's ref.
Most helpful comment
I have found a way to change background the color of the column.
Please let me know if I have done it the correct way or need some improvement.
Below is my code :
HTML Code:
TS Code:
Here is the output:

Hope this helps!!
Thanks